在使用R的分组操作之前,首先要了解R语言包,包实质上是实现特定功能的,预先写好的代码库(library),R拥有大量的软件包,许多包都是由某一领域的专家编写的,但并不是所有的包都有很高的质量的,在使用包之前,最好导社区中了解其他网友的反馈。
安装包,引用包和卸载包的命令分别是:
install.packages("package-name") library(package-name)remove.packages("package-name")
数据分析的工作,80%的时间耗费在处理数据上,而数据处理的过程可以分为:分离-操作-结合(Split-Apply-Combine),也就是说,先将数据根据特定的字段分组,每个分组都是独立的;然后,对每个分组执行转换,最后把转换后的结果组合在一起,在数据处理中,经常需要循环访问数据,R语言是矢量化的,天生具有处理循环操作的优势。
一,分组聚合
在apply函数家族中,apply函数只能用于矩阵,lapply函数能够用于向量和列表(list),其工作原理是把一个函数应用于一个列表中的每个元素上,并且把结果作为列表返回;sapply处理列表,返回向量。mapply函数,把调用的函数应用到多个列表的每一个元素中。
tapply函数用于分组聚合运算,在研究数据时,有时需要对数据按照特定的字段进行分组,然后统计各个分组的数据,这就是SQL语法中的分组聚合。在R语言中,可以通过三步实现:拆分-应用-合并(Split-Apply-Combine)
例如,对玩家的游戏成绩进行统计和分析,创建示例数据:
> players_scores=data.frame( + player=rep(c(‘Tom‘,‘Dick‘,‘Jim‘),times=c(2,5,3)), + score=round(runif(10,1,100),-1) + )
计算每个玩家的平均得分,首先对玩家分组,split函数的作用是按照特定的字段对数据框进行分组,第一个参数是数据框对象,第二个参数是分组字段,split函数返回的结果是列表对象。
例如,split(score,player)函数的作用是按照player字段把数据框中的score拆分成一组,也就是说,player 相同的score是同一个分组,填充到同一个列表项中:
> (scores_by_player=with(players_scores,split(score,player))) $Dick [1] 70 20 30 70 70 $Jim [1] 80 90 50 $Tom [1] 80 90
第二步是对每个分组计算平均分,利用lapply函数,把函数引用于列表的每个列表项中:
list_mean_by_player=lapply(scores_by_player,mean)
第三步是把结果合并到单个向量中,也就是把列表转换成向量,
> unlist(list_mean_by_player) Dick Jim Tom 52.00000 73.33333 85.00000
在数据分析中,”拆分-应用-合并“ 显示十分繁琐,tapply函数一次完成所有的三个步骤,一气呵成:
with(players_scores,tapply(score,player,mean))
tapply函数常用的参数共有三个,第一个参数是:数据框对象或向量,第二个参数是因子列表,也就是分组字段,第三个参数是指对单个分组应用的函数变量:
tapply(X, INDEX, FUN = NULL, ...)
by函数和aggregate函数是tapply函数的包装函数,功能相同,接口稍微不同。
二,aggregate函数
aggregate函数把数据分离为单独的子集,为每一个子集计算聚合值,然后把聚合值结合(combine)在一起返回。aggregate函数第一个参数是:price~cut,这是formula对象,包括符号“ ~”,以及在符号“~”两侧的变量,左侧代表要计算聚合值的变量(聚合变量),右侧代表分组的变量,函数依据分组变量,把数据分离为多个单独的子集。第二个参数是操作的数据框,第三个参数是应用在符号“~”左侧的函数,例如:
> library(ggplot2) > data("diamonds")
data函数的作用是加载指定的数据集,本例将加载ggplot2包中的diamonds数据集,这个数据集在下文直接引用。
使用aggregate函数操作diamonds数据集,按照cut字段分组,函数mean的作用是为每个分组计算prince的平均值:
> aggregate(price~cut,diamonds,mean)
aggregate函数能够添加多余一个的分组变量,只需要在formula右侧添加变量,并用加号“+”隔离:
> aggregate(price~cut+color,diamonds,mean) cut color price 1 Fair D 4291.061 2 Good D 3405.382 3 Very Good D 3470.467 ....
aggregate函数能够添加多个聚合变量,只需要在formula左侧,使用函数cbind把两个变量组合起来:
> aggregate(cbind(price,carat)~cut,diamonds,mean) cut price carat 1 Fair 4358.758 1.0461366 2 Good 3928.864 0.8491847 3 Very Good 3981.760 0.8063814 4 Premium 4584.258 0.8919549 5 Ideal 3457.542 0.7028370
还可以在aggregate函数formular对象的两侧分别添加多个变量执行操作
> aggregate(cbind(price,carat)~cut+color,diamonds,mean) cut color price carat 1 Fair D 4291.061 0.9201227 2 Good D 3405.382 0.7445166 ....
三,plyr包
plyr包基本上可以取代apply函数家族,plyr包核心函数的特点是:**ply,所有的函数名都由5个字符组成,且最后三个字符是ply,函数名的第一个字符代表输入值的类型,第二个字符代表输出值的类型。类型简写是:
- d:data.frame
- l:list
- a:array,vector,matrix
- r:代表replicate
- _:舍弃输出结果
plyr包的核心函数,使用起来十分方便,使用之前,需要加载和引用plyr包:
install.packages("plyr") library(plyr)
1,ddply函数
plyr包中最常用的函数是ddply函数,函数的第一个参数是要操作的数据框,第二个参数是:要进行拆分的列的名称,第三个参数是要应用到每个元素上的函数。传递列时,无需引号,但是需要包含在.(col_name)的调用之后。
使用colwise函数,使ddply函数把第三个参数引用于每一列,除了第二个参数指定的数据列之外,或者使用summarize函数对指定的列执行操作:
> ddply(diamonds,.(color),summarize,avg_price=mean(price),avg_carat=mean(carat)) color avg_price avg_carat 1 D 3169.954 0.6577948 2 E 3076.752 0.6578667.....
2,each函数
each函数,能够使函数aggregate函数同时调用多个函数
> aggregate(cbind(price,carat)~cut+color,diamonds,each(mean,sum)) cut color price.mean price.sum carat.mean carat.sum 1 Fair D 4291.061 699443.000 0.9201227 149.9800000 2 Good D 3405.382 2254363.000 0.7445166 492.8700000 ......
三,dplyr包
dplyr
包只能用于tibble类型的对象,用于对数据进行数据清理和转换,使用以下命令加载和引用dplyr包:
install.packages("dplyr") library(dplyr)
tibble 类型是dplyr包特有的对象类型(data frame tbl / tbl_df)。在利用dplyr
包处理数据之前,首先需要把数据框装载成tibble类型,可以调用 tbl_df
函数把数据框类型的数据装载成 tibble 类型的数据对象:
> df=tbl_df(diamonds)
1,投影函数(select)
从tibble变量中,选择特定的数据列显示,select函数的第一个参数是tibble变量:
> select(df,carat,cut,color)
2,筛选函数(filter)
从tibble变量中,按照特定的条件过滤数据:
> filter(df,color==‘E‘)
3,转换函数(mutate)
根据tibble变量中的数据,应用指定的公式,派生新的数据列,或重写已经存在的数据列:
> mutate(df,avg_ct=price/carat)
4,汇总函数(summarize)
对tibble变量执行聚合运算,如果tibble已经被分组,那么单独对每个分组进行聚合运算:
> summarize(df,avg_prince=mean(price),avg_ct=mean(carat))
5,分组函数(group_by)和移除分组(ungroup)
被分组之后,tibble变量处于分组状态,可以使用ungroup函数,移除tibble变量的分组状态。
group_by(df,color)
6,管道操作符(%>%)
管道操作符(%>%)用于把前一步操作的结果集(变量类型是tibble)传递到下一个函数中,赋值给函数的第一个参数中:
> group_by(df,color) %>% summarize(mean(price)) # A tibble: 7 x 2 color `mean(price)` <ord> <dbl> 1 D 3169.954 2 E 3076.752 3 F 3724.886 4 G 3999.136 5 H 4486.669 6 I 5091.875 7 J 5323.818
7,排序函数(arrange)
arrange对tibble变量进行排序,默认是按照字段的升序值排序,使用desc(field),可以按照字段的降序值排序:
> group_by(df,color) %>% summarize(avg_price=mean(price)) %>% arrange(desc(avg_price))
参考文档:
R语言滴水穿石系列文章(一):dplyr-高效的数据变换与整理工具