R数据处理包plyr:超越apply函数族的向量化运算
R有着强大而又丰富的数据处理能力,除了一些常用的基础数据处理函数之外,R还为我们提供了大量以实现不同的数据处理功能的扩展包。关注小编公众号的朋友应该还记得之前曾写过一篇关于R向量化运算的 apply
函数族的文章:
对于日常数据处理工作而言,可能 apply
函数族的8个核心函数还不够用,所以本篇小编为大家介绍一款基于 apply
函数族又超越了 apply
函数族的数据处理与转换包—— plyr
包。 plyr
包的设计理念在于切分(split)- 处理(apply)- 整合(combine)这样的一个数据处理流程,具体来说就是先对数据进行单/多变量或者维度的分割,然后对分割后的子数据集应用目标函数进行处理,最后将各子集处理后的结果汇集起来进行返回。这样的一套数据处理流程的方便之处在于 plyr
提供了16个有命名规律的核心函数,这些函数可以对各类输入数据经整合处理之后输出为指定的数据结构,简单易用方便快捷的实现数据变换和处理工作。
需要提到的是, plyr
包的作者依然是我们的 Hadley Wickham,Hadley大神除了ggplot2之外,也一直在致力于进行方便快捷的数据处理包的开发工作。
plyr包核心函数
plyr
包16个核心函数的命名都有相应的规律,函数具体形式如 XXply
,第一个 X
表示输入的R数据类型,第二个 X
表示需要输出的R数据类型,具体 X
的取值主要有:
a:array
d:data.frame
l:list
m:multiple inputs
_:nothing
比如说 adply
就表示输入为数组结构输出为数据框形式, dlply
就表示输入为数据框形式输出为列表形式,诸如此类。 plyr
包16个核心函数如下:
aaply
adply
alply
a_ply
daply
ddply
dlply
d_ply
laply
ldply
llply
l_ply
maply
mdply
mlply
m_ply
至于这些函数的具体用法,其实也是有规律可循的,以 ddply
函数的用法为例:
ddply(.data, .variables, .fun = NULL, ..., .progress = "none",
.inform = FALSE, .drop = TRUE, .parallel = FALSE, .paropts = NULL)
其中 .data
自然是待处理的输入数据,在 ddply
函数里指的是 data frame
; .variables
指的是用来对数据框进行分割的参数,可以是数据变量、式子或者一个字符串向量; .fun
就是应用在各个划分后的子数据集上的函数,核心参数就这三个,其他参数均是可选的,具体不在此一一释义。
plyr数据处理实例
下面小编以 aaply
、 dlply
和 ddply
三个核心函数为例,展示一下 plyr
包在数据处理方面的强大功能。
#aaply
library(plyr)
#求数据在1维上的均值
aaply(ozone, 1, mean)
-21.2 -18.7 -16.2 -13.7 -11.2 -8.7 -6.2 -3.7 -1.2
266.8194 263.0104 260.6493 258.8148 257.8657 256.9306 256.1007 255.6238 255.5081
1.3 3.8 6.3 8.7 11.2 13.7 16.2 18.7 21.2
255.0718 254.1771 254.5139 256.0729 258.8160 261.3009 263.7072 266.4005 269.9294
23.7 26.2 28.7 31.2 33.7 36.2
273.9062 279.5926 285.3356 293.2234 300.2546 308.7153
#.drop参数控制输出形式的数据相较于输入数据是否降维
dim(aaply(ozone, c(1,2), mean))
[1] 24 24
dim(aaply(ozone, c(1,2), mean, .drop = FALSE))
[1] 24 24 1
再来看 ddply
函数的使用:
#ddply
#创建一个数据框
dfx <- data.frame(
group = c(rep('A', 8), rep('B', 15), rep('C', 6)),
sex = sample(c("M", "F"), size = 29, replace = TRUE),
age = runif(n = 29, min = 18, max = 54)
)
#以group和sex分组计算均值和方差
ddply(dfx, .(group, sex), summarize,
mean = round(mean(age), 2),
sd = round(sd(age), 2))
group sex mean sd
1 A F 43.35 8.29
2 A M 38.49 8.64
3 B F 34.89 12.14
4 B M 43.65 10.25
5 C F 45.68 NA
6 C M 41.16 9.13
最后看一个 dlply
函数的例子:
#自定义一个回归函数
linmod <- function(df) {
lm(rbi ~ year, data = mutate(df, year = year - min(year)))
}
#使用dlply函数以.id变量进行切分对baseball数据集进行分组回归处理
models <- dlply(baseball, .(id), linmod)
models[[1]]
Call:
lm(formula = rbi ~ year, data = mutate(df, year = year - min(year)))
Coefficients:
(Intercept) year
118.924 -1.732
#后续还可以利用上述结果做一些可视化展示
coef <- ldply(models, coef)
with(coef, plot(`(Intercept)`, year))
qual <- laply(models, function(mod) summary(mod)$r.squared)
hist(qual)
参考资料:
http://127.0.0.1:31469/library/plyr/html/00Index.html
往期精彩:
使用jupyter notebook搭建数据科学最佳交互式环境
一个数据科学热爱者的学习历程