R tidyverse学习01

tidyverse 包是 Hadley Wickham 及团队的集大成之作,集数据读取,操作,探索和可视化于一体的一系列R包的集合。其理念是一开始先忽略编程的一些基础概念,如向量,矩阵,数据框,因子等,而是直接从数据的操作入手,可以有效的在短时间内学会数据的处理和可视化。但需要强调的一点是,如果想深入学习R语言以及其他编程语言,基础乃根本。

1. 基础

tibbles数据框和管道操作是学习tidyverse的基础。tibble是通过对传统的数据框功能的修改,开发的一种简单的数据框,更易于使用。在进行线性操作时,管道操作可以让你的代码看起来更加简洁,加代码的可读性。

tibbles数据框

  1. 通过 tibble()函数或 tribble()来创建新tibble, as_tibble()函数将数据框转换为tibble。
  2. tibble()函数当向量长度为1时,tibble会自动重复。
  3. tibble默认的数字类型为double。
  4. 相较于data.frame,tibble()的劣势在于其不能创建行名,不能改变输入的类型。
tibble(
  x = 1:4,
  y = 1,
  z = letters[1:4]
)

tribble(
  ~x, ~y, ~z,
  1,  1,  "a",
  2,  1,  "b",
  3,  1,  "c",
  4,  1,  "d"
)

tibble中也可以使用R中无效的变量名称,但需要加反引号。

tibble(
  `100` = 1:4,
  `<:` = 1,
  `:)` = letters[1:4]
)

在处理大数据集时,tibble在打印时,只显示前10行的结果;并且,借鉴于 str()函数,打印出每列的数据类型。

nycflights13::flights

2. 管道操作

管道操作%>%来源于Stefan Milton Bache开发的magrittr包,其原理是进行“词法变换”。在进行线性操作时,基于管道操作,可以优化代码,免去建议中间变量的繁琐步骤,增加代码的简洁性和可读性。并且管道操作也可用于基础函数,但是assign(),trycatch()等函数不适合于管道操作。

建议在操作步骤大于10,操作步骤复杂或有多个输入和输出的情况下最好不要使用管道。

# 对mtcars数据集每列求均值,函数不理解没关系,后续会讲到
mtcars %>% 
  as_tibble() %>% 
  summarise_all(mean)

更多的管道操作符可以使用help(package = "magrittr")查看。

2. 数据读写

数据读入

主要通过readr包的函数来实现。相较于基础函数,readr包函数的读取速度要快10倍左右,并且由于其不会集成操作系统的功能,因而更易重复使用。

  • read_csv()读取逗号分隔的文件;
  • read_csv2()读取分号分隔的文件;
  • read_tsv()读取制表符分隔的文件;
  • read_delim()读取任意字符分隔的文件;
  • read_fwf()读取固定宽度的文件;
  • read_table()读取空白字符分隔的文件;
  • ......

此外,常见的excel文件可以使用readxl包的 read_excel, read_xls(), read_xlsx()函数读取;SPSS、Stata 和 SAS ⽂件可以通过haven包读取;JSON串通过jsonlite包读取;XML通过xml2包读取。

以read_csv()函数为例,其主要参数如下:

这里我提前将iris数据集保存到本地,再使用read_csv来读取。

data <- read_csv("iris.csv")

数据写出

readr包提供的write_系列函数用于数据的写出,其中, write_csvwrite_tsv()最常见,因为他们使用UTF-8对字符串编码,使用ISO8601格式保存时间数据,所以他们生成的文件能顺利读取的概率更高。此外,wrtie_excel_csv()可以生成excel文件。

3. 基于dplyr的数据转换

基于nycflights13::flights和mtcars数据集,介绍dplyr包中的基础操作。具体可使用?flights和?mtcars查看。

数据筛选

filter()函数中的多个参数之间是通过“与”组合起来的。

筛选出12月31日的航班信息

nycflights13::flights %>% 
  filter(month == 12, day == 31)

此外,filter_系列函数还包括filter_all(),filter_at(), filter_if()函数。

  1. filter_all 该函数对数据框中的每一行都进行筛选操作。
# 筛选任一列中大于150的行
# 辅助函数还有all_vars
mtcars %>% 
  filter_all(any_vars(. > 150))
  1. filter_at
# 筛选所有d开头的列变量都能够被2整除的行
mtcars %>% 
  filter_at(vars(starts_with("d")), any_vars((. %% 2) == 0))
  1. filter_if
# 首先将所有列的值转换不大于某个值的最大整数值,然后使用all函数判断转换前后值是否相同而产生逻辑值,当值为TRUE时,筛选出所有列均不等于0的观测值
mtcars %>% 
  filter_if(~ all(floor(.) == .), all_vars(. != 0))

数据选择

select()函数基于变量名操作,可以快速生成一个有用的变量子集。

nycflights13::flights %>% 
  select(year, month, dep_time)
nycflights13::flights %>% 
  select(year:dep_time)

select也可以使用“-”选择不在某个范围内,或者非某个变量名的列。

nycflights13::flights %>% 
  select(-(year:dep_time))

在 select() 函数中还可以使⽤⼀些辅助函数:

  • starts_with("abc") :匹配以 abc 开头的名称。
  • ends_with("xyz") :匹配以 xyz 结尾的名称。
  • contains("ijk") :匹配包含 ijk 的名称。
  • matches("(.)\1") :选择匹配正则表达式的那些变量。这个正则表达式会匹配名称中有重复字符的变量。
  • num_range("x", 1:3) :匹配 x1、x2 和 x3。

以ends_with为例:

nycflights13::flights %>% 
  select(ends_with("time"))

此外,与filter函数类似,select系列还有select_at(), select_if(),select_all()等,具体可以通过help()查看,用法与filter类似。

数据排列

arrange()函数基于选择的列,对数据框的行进行排序。如果参数不止一个,则在前一个参数排序的基础上再进行排序。默认是升序,使用desc()函数可以进行降序排列,缺失值总排在最后。

nycflights13::flights %>% 
  arrange(desc(month), dep_time)

那么,一次性想选择多列进行排序,该如何实现呢?across()函数为我们提供了解决办法,其能够同时对多列应用函数。

nycflights13::flights %>% 
  arrange(across(year:month))

同样,arrange也存在三种变体,同样是at, all, if系列,具体使用参见函数帮助文档。

添加新变量

mutate()函数,其也有at,all,if变体系列。此外,还有mutate_each()mutate_each_()函数,但是,在dplyr 0.7.0.中,mutate_each_()被弃用,作者建议使用across()函数代替。

nycflights13::flights %>% 
  .[, 4:8] %>% 
  mutate(time = dep_time - arr_time)
mtcars %>% 
  .[1:41:4] %>% 
  mutate_each(mean)

分组、统计

group_by() 可以将分析单位从整个数据集更改为单个分组。接下来,在分组后的数据框上使⽤ dplyr 函数时,它们会⾃动地应⽤到每个分组,取消分组使用 ungroup()函数。常用的是分组后使用summmarise()函数。

flights %>%
  group_by(dest) %>%
  summarise(
    count = n(),
    dist = mean(distance, na.rm = TRUE),
    delay = mean(arr_delay, na.rm = TRUE)
  ) %>%
  filter(count > 20, dest != "HNL")

值得注意的是,当使⽤多个变量进⾏分组时,每次的摘要统计会⽤掉⼀个分组变量。这样就可以轻松地对数据集进⾏循序渐进的分析。 group_by()和summarise()函数也有一系列变体,建议通过阅读帮助文档学习,感觉大同小异(个人观点)。

重命名列

rename() 通过赋值的形式来改变列名; rename_with()函数通过传递函数实现改变列名.当然,它也也诸多变体函数,在这里不一一介绍。

mtcars %>% 
  .[1:41:4] %>% 
  rename(Mpg = mpg)
mtcars %>% 
  .[1:41:4] %>% 
  rename_with(str_to_title)

长宽数据转换

  1. 宽数据格式变长数据格式

⼀种常⻅的问题是数据集中某些列名不是变量名,而是变量值。为了整理这样的数据集,我们需要将有问题的列旋转到⼀对新的变量中。

tidyr::table4a %>%
  pivot_longer(
    c(`1999`, `2000`),
    names_to = "year",
    values_to = "cases")
  1. 长数据格式变宽数据格式 为了方便,我们将上一部分得到的数据重新转成宽数据格式。
tidyr::table4a %>%
  pivot_longer(
    c(`1999`, `2000`),
    names_to = "year",
    values_to = "cases") %>%
  pivot_wider(
    names_from = year, 
    values_from = cases)

列的拆分、合并

separate()函数能够依据分隔符分隔列,unite()是其反向操作函数。

tidyr::table3 %>%
  separate(
    rate,
    into = c("cases""population"),
    sep = '/')
library(lubridate)
nycflights13::flights %>% 
  .[, 1:3] %>% 
  unite("ymd", year, month, day, remove = F) %>% 
  mutate(ymd = as_date(ymd))

欢迎关注我的微信公众号。
在这里插入图片描述

参考

  1. 《R数据科学》
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值