plyr包可以将函数运行在某个R对象上,经过Split-Apply-Combine把数据集分割成更小的数据集,对分割后的数据应用函数,最后汇总计算结果。根据不同的输入对象类型(数组,数据框或列表)plyr提供了不同的函数,输出数组,数据框,列表或者选择不输出。plyr的优势在于能够以简洁的代码替换复杂的循环操作,进而提高计算性能。以下为plyr包的主要函数:
输入对象 | 输出矩阵 | 输出数据框 | 输出列表 | 不输出 |
array | aaply | adply | alply | a_ply |
data.frame | daply | ddply | dlply | d_ply |
list | laply | ldply | llply | l_ply |
matrix/data.frame | maply | mdply | mlply | m_ply |
n replicates | raply | rdply | rlply | r_ply |
1. 输入为数组
#输入数组,输出数组 aaply(.data, .margins, .fun = NULL, ..., .expand = TRUE, .progress = "none", .inform = FALSE, .drop = TRUE, .parallel = FALSE, .paropts = NULL) #输入数组,输出数据框 adply(.data, .margins, .fun = NULL, ..., .expand = TRUE, .progress = "none", .inform = FALSE, .parallel = FALSE,.paropts = NULL, .id = NA) #输入数组,输出列表 alply(.data, .margins, .fun = NULL, ..., .expand = TRUE, .progress = "none", .inform = FALSE, .parallel = FALSE,.paropts = NULL, .dims = FALSE) #输入数组,放弃输出结果 a_ply(.data, .margins, .fun = NULL, ..., .expand = TRUE, .progress = "none", .inform = FALSE, .print = FALSE, .parallel = FALSE, .paropts = NULL) |
x <- array(1:24, 2:4)
#对第一维求和,返回3×4的矩阵
aaply(x, c(2,3), sum)
#对第二维求和,返回2×4的矩阵
aaply(x, c(1,3), sum)
#对第三维求和,返回2×3的矩阵
aaply(x, c(1,2), sum)
#对第二和第三维求和,返回length=2(第一维)的向量
aaply(x, 1, sum)
#对第一和第三维求和,返回length=3(第二维)的向量
aaply(x, 2, sum)
#对第一和第二维求和,返回length=4(第二维)的向量
aaply(x, 3, sum)
#对数组第二和第三维求平均,返回length和第一维相同的向量,24×1的向量
aaply(ozone, 1, mean)
#对数组第二和第三维求平均,返回24×2的matrix
aaply(ozone, 1, mean, .drop = FALSE)
#对数组第二和第三维求平均,返回24×2的data.frame
adply(ozone, 1, mean)
#对数组第二和第三维求平均,返回list
alply(ozone, 1, mean)
#对数组第一和第三维求平均,返回length和第一维相同的向量,24×1的向量
aaply(ozone, 2, mean)
#对数组第一和第二维求平均,返回length和第三维相同的向量,72×1的向量
aaply(ozone, 3, mean)
#对数组第三维求平均,返回24×24 matrix
aaply(ozone, c(1,2), mean)
#返回24×24,默认丢弃额外的维度
dim(aaply(ozone, c(1,2), mean))
#返回24×24×1
dim(aaply(ozone, c(1,2), mean, .drop = FALSE))
#对数组第二和第三维应用each组合的min和max函数,返回24×2的matrix
aaply(ozone, 1, each(min, max))
#对数组第一和第二维应用each组合的min和max函数,返回72×2的matrix
aaply(ozone, 3, each(min, max))
standardise <- function(x) (x - min(x)) / (max(x) - min(x))
#对第一维和第二维应用函数,对每个元素进行标准化,返回24×24×72的array
aaply(ozone, 3, standardise)
#对第三维应用函数,对每个元素进行标准化,返回24×24×72的array
aaply(ozone, 1:2, standardise)
2. 输入为数据框
#输入数据框,输出数组 daply(.data, .variables, .fun = NULL, ..., .progress = "none", .inform = FALSE, .drop_i = TRUE, .drop_o = TRUE, .parallel = FALSE, .paropts = NULL) #输入数据框,输出数据框 ddply(.data, .variables, .fun = NULL, ..., .progress = "none", .inform = FALSE, .drop = TRUE, .parallel = FALSE, .paropts = NULL) #输入数据框,输出列表 dlply(.data, .variables, .fun = NULL, ..., .progress = "none", .inform = FALSE, .drop = TRUE, .parallel = FALSE, .paropts = NULL) #输入数据框,放弃输出结果 d_ply(.data, .variables, .fun = NULL, ..., .progress = "none", .inform = FALSE, .drop = TRUE, .print = FALSE, .parallel = FALSE, .paropts = NULL) |
#按year分组,统计每个分组的行数
daply(baseball, .(year), nrow)
ddply(baseball, .(year), nrow)
dlply(baseball, .(year), nrow)
#按team分组,分别对g列求和,r列求平均
ddply(baseball, .(team), summarise, sum(g), mean(r))
#按year分组,对特定的每个列求均值
daply(baseball[, c(2, 6:9)], .(year), colwise(mean))
daply(baseball[, c(2, 6:9)], .(year), colwise(mean, na.rm = TRUE))
daply(baseball[, 6:9], .(baseball$year), colwise(mean))
daply(baseball, .(year), function(df) colwise(mean)(df[, 6:9]))
3. 输入为列表
#输入列表,输出数组 laply(.data, .fun = NULL, ..., .progress = "none", .inform = FALSE, .drop = TRUE, .parallel = FALSE, .paropts = NULL) #输入列表,输出数据框 ldply(.data, .fun = NULL, ..., .progress = "none", .inform = FALSE, .parallel = FALSE, .paropts = NULL, .id = NA) #输入列表,输出列表 llply(.data, .fun = NULL, ..., .progress = "none", .inform = FALSE, .parallel = FALSE, .paropts = NULL) #输入列表,放弃输出结果 l_ply(.data, .fun = NULL, ..., .progress = "none", .inform = FALSE, .print = FALSE, .parallel = FALSE, .paropts = NULL) |
#判断对象baseball中的列是否为factor类型,返回逻辑值矩阵
laply(baseball, is.factor)
ldply(baseball, is.factor)
colwise(is.factor)(baseball)
a <- 1:100
b <- seq(from = 1,to = 100,by = 2)
c <- runif(150,min = 1,max = 100)
nList <- list(a = a,b = b,c = c)
#求list中每个元素的均值
laply(nList, mean)
#对list中每个元素应用summary函数
ldply(nList, summary)
#对list中每个元素应用quantile函数
llply(nList, quantile)
4. 输入对象作为fun的参数
#输入作为fun的参数,输出数组 maply(.data, .fun = NULL, ..., .expand = TRUE, .progress = "none", .inform = FALSE, .drop = TRUE, .parallel = FALSE, .paropts = NULL) #输入作为fun的参数,输出数据框 mdply(.data, .fun = NULL, ..., .expand = TRUE, .progress = "none", .inform = FALSE, .parallel = FALSE, .paropts = NULL) #输入作为fun的参数,输出列表 mlply(.data, .fun = NULL, ..., .expand = TRUE, .progress = "none", .inform = FALSE, .parallel = FALSE, .paropts = NULL) #输入作为fun的参数,放弃输出结果 m_ply(.data, .fun = NULL, ..., .expand = TRUE, .progress = "none", .inform = FALSE, .print = FALSE, .parallel = FALSE,.paropts = NULL) |
#输入对象作为rnorm函数的入参,返回5×5×5的矩阵,仅对角线有值
maply(cbind(mean = 1:5, sd = 1:5), rnorm, n = 5)
maply(cbind(1:5, 1:5), rnorm, n = 5)
#输入对象作为rnorm函数的入参,返回5×5×5的矩阵
maply(expand.grid(mean = 1:5, sd = 1:5), rnorm, n = 5)
#输入对象作为rnorm函数的入参,返回数据框
mdply(cbind(mean = 1:5, sd = 1:5), rnorm, n = 5)
mdply(expand.grid(mean = 1:5, sd = 1:5), rnorm, n = 5)
#输入对象作为rnorm函数的入参,返回List对象
mlply(cbind(mean = 1:5, sd = 1:5), rnorm, n = 5)
mlply(expand.grid(mean = 1:5, sd = 1:5), rnorm, n = 5)
#输入对象作为rep函数的入参,返回List对象
mlply(cbind(1:4, 4:1), rep)
mlply(cbind(1:4, 4:1), seq)
5. 输入表达式
#对表达式求值n次,返回求值结果组成的array raply(.n, .expr, .progress = "none", .drop = TRUE) #对表达式求值n次,返回求值结果组成的data.frame rdply(.n, .expr, .progress = "none", .id = NA) #对表达式求值n次,返回求值结果组成的list rlply(.n, .expr, .progress = "none") #对表达式求值n次,放弃输出结果 r_ply(.n, .expr, .progress = "none", .print = FALSE) |
#计算表达式100次,返回vector
raply(100, mean(runif(100)))
#计算表达式100次,返回matrix
raply(100, each(mean, var)(runif(100)))
#计算表达式10次,返回10×2×2的array
raply(10, matrix(runif(4), nrow=2))
#计算表达式20次,返回20×3的data.frame
rdply(20, each(mean, var)(runif(100)))
#计算表达式20次,返回length = 20的list
rlply(20, each(mean, var)(runif(100)))
6. each集合多个函数为一个
plyr包中的each函数可以用于结合多个函数为一个,返回向量的名称为函数名。其中参数…用于输入函数集合,组合的函数输出不要求一定是单输出。
each(...) |
#对向量1:10调用函数min和max
each(min, max)(1:10)
each("min", "max")(1:10)
each(c(min, max))(1:10)
each(c("min", "max"))(1:10)
#使用each创建函数
f<- each(min, max)
f(1:10)
#对随机正态向量调用length,mean和var函数
each(length, mean, var)(rnorm(100))
#使用fivenum函数
each(min, fivenum)(1:10)
7. colwise对每个列应用函数
plyr包中的colwise函数可以用于对data.frame的每个列使用函数,可以与d*ply函数联合使用。
#对data.frame的每一列使用函数.fun colwise(.fun, .cols = true, ...) #只对离散变量使用函数.fun catcolwise(.fun, ...) #只对数值变量使用函数.fun numcolwise(.fun, ...) |
#统计缺失值个数
nmissing <- function(x) sum(is.na(x))
#对baseball的每列使用nmissing函数
colwise(nmissing)(baseball)
#使用colwise函数创建统计每列缺失值的函数
f <- colwise(nmissing)
f(baseball)
#只对numeric类型变量应用函数
numcolwise(nmissing)(baseball)
colwise(nmissing, is.numeric)(baseball)
#只对discrete变量应用函数
catcolwise(nmissing)(baseball)
colwise(nmissing, is.discrete)(baseball)
#统计缺失值个数
nmissing <- function(x) sum(is.na(x))
#按year分组,对分组后的每个列应用函数
ddply(baseball, .(year), colwise(nmissing))
#按year分组,对分组后的特定列使用函数
ddply(baseball, .(year), colwise(nmissing, .(sb, cs, so)))
ddply(baseball, .(year), colwise(nmissing, c("sb", "cs", "so")))
ddply(baseball, .(year), colwise(nmissing, ~ sb + cs + so))
#按year分组,使用boolean函数筛选需要应用函数的变量
ddply(baseball, .(year), colwise(nmissing, is.character))
ddply(baseball, .(year), colwise(nmissing, is.numeric))
ddply(baseball, .(year), colwise(nmissing, is.discrete))
#按year分组,只对numeric类型变量应用函数
ddply(baseball, .(year), numcolwise(nmissing))
#按year分组,只对discrete变量应用函数
ddply(baseball, .(year), catcolwise(nmissing))
#给函数传递参数na.rm = TRUE, 两种方法等效
numcolwise(mean)(baseball, na.rm = TRUE)
numcolwise(mean, na.rm = TRUE)(baseball)
两年前写的东西了,会逐步都发出来,有很多新函数暂时就不更新了 :(