文章目录
R语言系列:
- 编程基础💎循环语句💎向量、矩阵和数组💎列表、数据帧
- 排序函数💎apply系列函数
- tidyverse:readr💎tibble💎tidyr💎dplyr
简介和数据准备
dplyr,这个吊诡的名字,可以强行拆分成dataframe ply for r,其中ply有穿梭的意思,而dplyr的操作逻辑,也类似于让数据框在一些函数中穿梭的感觉。
dplyr提供一个管道操作%>%,其左侧为输入的数据,右侧为处理这个数据的函数,就像这个符号的形状一样,数据框穿过函数,得到新的值。形如a %>% f(b,c..)的表达式,等价于f(a, b, c,...)。
此外,为了操作数据框,dplyr主要提供了列选择、筛选、统计等函数,下面以鸢尾花数据集为例,逐个测试这些函数,并比对常规写法和管道写法。
鸢尾花数据集的前五行如下
> head(iris, 5)
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1 5.1 3.5 1.4 0.2 setosa
2 4.9 3.0 1.4 0.2 setosa
3 4.7 3.2 1.3 0.2 setosa
4 4.6 3.1 1.5 0.2 setosa
5 5.0 3.6 1.4 0.2 setosa
# 下面是dplyr提供的切片函数,也可以显示1到5行数据
> slice(iris, 1:5)
glimpse函数可以更加便捷地显示数据的主要信息
> glimpse(iris)
Rows: 150
Columns: 5
$ Sepal.Length <dbl> 5.1, 4.9, 4.7, 4.6, 5.0, 5.4, 4.6, 5.0, 4.4, 4…
$ Sepal.Width <dbl> 3.5, 3.0, 3.2, 3.1, 3.6, 3.9, 3.4, 3.4, 2.9, 3…
$ Petal.Length <dbl> 1.4, 1.4, 1.3, 1.5, 1.4, 1.7, 1.4, 1.5, 1.4, 1…
$ Petal.Width <dbl> 0.2, 0.2, 0.2, 0.2, 0.2, 0.4, 0.3, 0.2, 0.2, 0…
$ Species <fct> setosa, setosa, setosa, setosa, setosa, setosa…
行列筛选
select可以按照列选择数据,filter则按照行来筛选数据。在这两个函数中,可调用starts_with, ends_with, contains等函数来判断列名等是否符合筛选要求。
select示例如下
# 选择第1列到第三列
select(iris,1:3)
select(iris,c(1,2,3))
# 选择Sepal.Length到Petal.Lengthiris中的所有列,即1,2,3列
select(iris,"Sepal.Length":"Petal.Length")
# 除了Sepal.Length的列
select(iris,-Sepal.Length)
# 选择以"S"开头,且以"h"结尾的列,即1, 2列
select(iris,starts_with("S")&ends_with("h"))
其中,starts_with和ends_with分别用于检测每一列的列名,通过对二者进行与&,或|,非!等操作,可以更加细致地筛选出符合条件的列名称。在数据筛选时,可用到的检测函数包括
starts_with, ends_with以某字符串开始或结尾的列contains包含某个字符串的列one_of输入为字符串向量,若某列名在这组向量中,则选择everything()所有列matches符合指定表达式规则的列
以select(iris, 1:3)为例,其管道表达式为
iris %>% select(1:3)
filter示例如下
# 筛选出Sepal.Length小于Sepal.Width*1.3的行
> filter(iris, iris$Sepal.Length < iris$Sepal.Width*1.3)
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1 5.7 4.4 1.5 0.4 setosa
2 4.6 3.6 1.0 0.2 setosa
3 5.2 4.1 1.5 0.1 setosa
此外,dplyr还提供了sample_frac, sample_n,用于随机挑选数据,例如
sample_frac(iris, 0,5) # 随机挑选百分之50的数据
sample_n(iris, 5) # 随机挑选5条数据
mutate
mutate函数可以根据相应规则,在数据框中添加一列,例如下面就是在最后添加了一个名为id的列,这一列的内容是数据所在行数。
> mutate(iris, id=row_number()) %>% head(2)
Sepal.Length Sepal.Width Petal.Length Petal.Width Species id
1 5.1 3.5 1.4 0.2 setosa 1
2 4.9 3.0 1.4 0.2 setosa 2
在mutate中可供选择的列添加方案有很多,大概分为下面几类
- 排序:
dense_rank,min_rank, 百分比排序percent_rank - 分割:
ntile,按照大小,将数据分成多份 - 提前、延后:
lead将数据向前挪一位,lag则向后挪一位,空出的位置补充NA - 累积函数,原生R语言中有4个累积统计函数,分别是求和、求积、最大值、最小值:
cumsum, cumprod, cummax, cummin;dplyr补充了三个:cumall, cumany, cummean。
# 添加列为Sepal.Length列 从小到大排序的序号
mutate(iris, id=min_rank(Sepal.Length))
# 将Sepal.Length按照大小值分割为五份,新增列为其第几份的序号
mutate(iris, id=ntile(Sepal.Length, 5))
# 新增列为Sepal.Length累积求和
mutate(iris, id=cumsum(Sepal.Length))
数据概述
数据概述
通过summarise可进行数据概述,用以求出数据框某一行的统计信息,例如
>summarise(iris, MeanLength=mean(Sepal.Length))
MeanLength
1 5.843333
mean是均值函数,如果不用summarise,则需要用下面的方法求均值
> mean(iris$Sepal.Length)
[1] 5.843333
summarize可调用的统计函数,包括R语言自带的min, max, mean, median, 方差var, 标准差sd, 四分位距IRQ之外,还可以用dplyr中的first, last, nth, n, n_distinct,其中nth需要额外输入一个参数n,表示向量第n个值;n_distinct表示向量中不同元素的个数。
除了summarise,dplyr还可使用summarise_each,可对每一列进行数据统计
> summarise_each(iris, list(mean=mean), -Species)
Sepal.Length_mean Sepal.Width_mean Petal.Length_mean Petal.Width_mean
1 5.843333 3.057333 3.758 1.199333
如果希望对数据进行按组统计,就需要用到group_by函数,其功能是数据分组,此外dplyr还提供了其对偶函数ungroup用于取消分组。
> iris %>% group_by(Species) %>% summarise(mean(Sepal.Length))
# A tibble: 3 × 2
Species `mean(Sepal.Length)`
<fct> <dbl>
1 setosa 5.01
2 versicolor 5.94
3 virginica 6.59
集合运算
dplyr中提供了类似交集、并集、差集的运算,当然操作的其实是数据框
intersect(y, z)返回y和z中都出现的数据union(y,z)返回y或z中出现的数据,类似并集setdiff(y,z)返回y中有,z中无的数据
和交集,差集相比,并集类似于添加数据,所以相对复杂,dplyr还提供了下面两个函数,用于将一维数据添加到数据框,参数为(y, z)
bind_rows, bind_cols将z作为新行/列添加到y中
dplyr中提供了数据集合并函数,输入参数均为(a,b,by=)包括下列函数
left_join, right_join向a中加入b/向b中加入ainner_join, outer_join合并数据,前者仅保留匹配记录,后者保留所有记录semi_join, anti_join分别合并匹配和不匹配的数据
杂项
dplyr提供了data_frame函数,可以将向量合并为数据框。
> data_frame(c(1:3), 2:4)
# A tibble: 3 × 2
`c(1:3)` `2:4`
<int> <int>
1 1 2
2 2 3
3 3 4
arrange可对数据进行排序,例如
# 将Sepal.Length列从大到小排序
arrange(iris, -Sepal.Length)










