查看原文
其他

使用plyr包进行数据处理

2016-01-15 刘顺祥 每天进步一点点2015

在上一期文章中介绍了强大的dplyr包,该包在数据预处理中显得尤为方便快捷,可以实现数据的筛选、聚合、连接、合并、访问MySQL数据库等,具体可见链接:强大的dplyr包实现数据预处理


本文将着重介绍一下同一个作者开发的plyr包,该包与dplyr包既有相似的地方,也有不同的地方。plyr包最让我兴奋的地方是可以方便的实现数据结构之间的转换,具体见下文的详细说明。


首先看一张表格:


这张表格的蓝色三行为输入的数据结构,蓝色四列为输出的数据结构,红色为R函数,均已ply结尾,前面两个字母代表“输入+输出数据结构的首字母”。在了解了函数书写特征后,我们具体来扒一扒函数的使用方法和参数设置。


函数介绍

a*ply函数格式

aaply(.data = ,.margins = ,.fun = ,...,.progress = 'none',.inform = FALSE)

adply(.data = ,.margins = ,.fun = ,...,.progress = 'none'.inform = FALSE)

alply(.data = ,.margins = ,.fun = ,...,.progress = 'none'.inform = FALSE)

a_ply(.data = ,.margins = ,.fun = ,...,.progress = 'none'.inform = FALSE)

.data可以是数组也可以是矩阵;

.margins指定要分析的数组或矩阵的维度,即行维(.margins = 1)还是列维(.margins = 2);

.fun为行维或列维指定需要处理的函数,可以是R自带的函数,如sum(),mean()等,也可以是自定义函数;

...为指定函数的其他参数;

.progress指定以什么样的方式展示程序运行的进度,默认不显示进度,还可以选择"text"(文本进度条), "tk"(tk进度条), 和"win"(Windows系统自带的进度条);

.inform是否指定报错信息,默认不指定,因为设为TRUE的话,将降低程序的执行效率,但该参数对Bug处理是有帮助的。


例子:

library(plyr)

a <- array(data=1:500000,dim=c(100000,5))

#对每一行求均值,不显示进度条

test1 <- aaply(.data = a,.margins = 1,.fun = mean, .progress = 'none')

head(test1)



#对每一行求标准差,以文本形式显示进度条

test2 <- adply(.data = a,.margins = 1,.fun = sd, .progress = 'text')

head(test2)



#对每一列求和,以tk形式显示进度条

a2 <- array(rnorm(10000000), dim = c(1000,10000))

test3 <- alply(.data = a2,.margins = 2,.fun = sum, .progress = 'tk')


#对每一列求最大值,以Windows自带进度条显示进度

a3 <- array(rnorm(10000000), dim = c(100,100000))

test4 <- a_ply(.data = a3,.margins = 2,.fun = max, .progress = 'win')



#d*ply函数格式

daply(.data = ,.variables = ,.fun = ,...,.progress = 'none',.inform = FALSE)

ddply(.data = ,.variables = ,.fun = ,...,.progress = 'none',.inform = FALSE)

dlply(.data = ,.variables = ,.fun = ,...,.progress = 'none',.inform = FALSE)

d_ply(.data = ,.variables = ,.fun = ,...,.progress = 'none',.inform = FALSE)

.data指定为数据框数据;

.variables指定数据框中的分组变量;

.fun基于分组变量,可对数据框中的其余变量指定某种函数,可以是R自带的函数,如sum(),mean()等,也可以是自定义函数,类似于聚合分析;

.progress和.inform与a*ply函数参数一致。


例子:

#构建自定义函数

fun <- function(data) apply(data,2,mean)


daply(.data = iris[,1:4],.variables = .(iris$Species),.fun=fun)

ddply(.data = iris[,1:4],.variables = .(iris$Species),.fun=fun)

dlply(.data = iris[,1:4],.variables = .(iris$Species),.fun=fun)

d_ply(.data = iris[,1:4],.variables = .(iris$Species),.fun=fun)



l*ply函数格式

laply(.data = ,.fun = ,...,.progress = 'none',.inform = FALSE)

ldply(.data = ,.fun = ,...,.progress = 'none',.inform = FALSE)

llply(.data = ,.fun = ,...,.progress = 'none',.inform = FALSE)

l_ply(.data = ,.fun = ,...,.progress = 'none',.inform = FALSE)

.data可以指定为列表数据,也可以指定为向量数据;

其余参数与a*ply()函数和d*lpy()函数参数一致。


例子:

x1 <- 1:100

x2 <- seq(from = 100,to = 1000 ,by = 2)

x3 <- runif(150,min = 10,max = 100)

#列表由向量构成

l1 <- list(x1 = x1,x2 = x2,x3 = x3)


laply(.data = l1,.fun = mean)

ldply(.data = l1,.fun = summary)

llply(.data = l1,.fun = quantile)

l_ply(.data = l1,.fun = summary)


#构建数据框d11

y11 <- rnorm(n = 100,mean = 10,sd = 5)

y12 <- rt(n = 100,df = 3)

y13 <- rf(n = 100,df1 = 2,df2 = 3)

y14 <- factor(x = c('low','potential','high'),ordered = T)

y15 <- sample(y14,size = 100,replace = TRUE)

d11 <- data.frame(y1 = y11,y2 = y12,y3 = y13,y5 = y15)

head(d11)


#构建数据框d21

y21 <- 1:100

y22 <- seq(from = 1,to = 2,length = 100)

y23 <- rchisq(n = 100,df = 8)

y24 <- factor(x = c('A','B','C','D'),ordered = T)

y25 <- sample(y24,size = 100,replace = TRUE)

d21 <- data.frame(y21 = y21,y22 = y22,y23 = y23,y25 = y25)

head(d21)


#列表由数据框组成

l2 <- list(first = d11,second = d21)


library(psych)

fun <- function(data) describeBy(data[,1:3],group = data[,4])

llply(.data = l2,.fun = fun,.progress = 'none')

llply(.data = l2,.fun = fun,.progress = 'text')

返回结果如下(部分)


plyr包中还有很多其他函数,如rename()、arrange()、join()等函数,其功能与dplyr包中的rename()、arrange()、left_join()一致,这里不再赘述。这两个包可以相辅相成,互补缺陷,各显优势,所以在数据预处理过程中可以考虑结合使用这两个包,一定能使工作效率得到大幅提升。

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存