当前位置: 首页 > 工具软件 > Plyr > 使用案例 >

【R语言】必学包之plyr包

高吉星
2023-12-01

 

       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)

  • data:输入的数据对象;
  • margins:分割数据的小表向量,1按行分割,2列分割,c(1, 2) 按行和列分割;对多维数组,margins中不包括的维,即为应用函数的维,例如,三维array,设置margins = c(1,3)表示对第二维应用函数;
  • fun:需要执行的函数、
  • …:fun中所需的额外参数
  • expand:用于控制输出如何扩展,如果.data是一个数据框,TRUE(默认值)表示1维输出,FALSE为n维输出;
  • progress:进度条类型,none(默认值)没有进度条,text,tk和win
  • inform:是否产生错误信息,默认情况下为关闭状态(FALSE),多在调试时打开(TRUE),因为会大大减缓处理速度;
  • parallel:指定是否并行的运行函数(通过foreach),默认为FALSE不并行运行
  • paropts:parallel为TRUE时,用于设置传递给foreach的参数;
  • drop:在维度为1的输出中是否丢弃额外的维度,默认为TRUE;
  • id:用于设置索引列的名称,默认值为NA,使用名称“X1“,”X2“,……
  • print:指定是否在屏幕上打印每个输出值,默认为FLASE
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)

  • data:输入的数据框对象;
  • variables:指定分割数据框的一系列变量;
  • fun:需要执行的函数;
  • …:fun中所需的额外参数
  • progress:进度条类型,none(默认值)没有进度条,text,tk和win
  • inform:是否产生错误信息,默认情况下为关闭状态(FALSE),多在调试时打开(TRUE),因为会大大减缓处理速度;
  • drop(和drop_i):是否放弃输入数据中未出现的变量组合,默认为TRUE;
  • drop_o:在维度为1的输出中是否丢弃额外的维度,默认为TRUE;
  • parallel:指定是否并行的运行函数(通过foreach),默认为FALSE不并行运行
  • paropts:parallel为TRUE时,用于设置传递给foreach的参数;
  • print:指定是否在屏幕上打印每个输出值,默认为FLASE
#按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)

  • data:输入的列表对象
  • fun:需要执行的函数
  • …:fun中所需的额外参数
  • progress:进度条类型,none(默认值)没有进度条,text,tk和win
  • inform:是否产生错误信息,默认情况下为关闭状态(FALSE),多在调试时打开(TRUE),因为会大大减缓处理速度
  • parallel:指定是否并行的运行函数(通过foreach),默认为FALSE不并行运行
  • paropts:parallel为TRUE时,用于设置传递给foreach的参数;
  • drop:在维度为1的输出中是否丢弃额外的维度,默认为TRUE;
  • id:用于设置索引列的名称,为NA时,避免转换索引列为因子;
  • print:指定是否在屏幕上打印每个输出值,默认为FLASE
#判断对象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)

  • data:矩阵或数据框;
  • fun:需要执行的函数
  • …:fun中所需的额外参数
  • expand:用于控制输出如何扩展,如果.data是一个数据框,TRUE(默认值)表示1维输出,FALSE为n维输出;
  • progress:进度条类型,none(默认值)没有进度条,text,tk和win
  • inform:是否产生错误信息,默认情况下为关闭状态(FALSE),多在调试时打开(TRUE),因为会大大减缓处理速度;
  • parallel:指定是否并行的运行函数(通过foreach),默认为FALSE不并行运行
  • paropts:parallel为TRUE时,用于设置传递给foreach的参数;
  • drop:是否删除输出对象中额外的长度为1的维度信息,默认为TRUE;
  • print:指定是否在屏幕上打印每个输出值,默认为FLASE
#输入对象作为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)

  • n:对表达式求值的次数;
  • expr:表达式;
  • progress:使用的进度条的名称
  • drop:是否删除输出对象中额外的长度为1的维度信息,默认为TRUE;
  • id:用于设置索引列的名称,为NA时,避免转换索引列为因子;
  • print:指定是否在屏幕上打印每个输出值,默认为FLASE
#计算表达式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, ...)

  • fun:给定需要执行的函数
  • cols:列向量用于给出需要处理的列,或者输出为Boolean类型的函数用于筛选出需要处理的列
  • …:传递给函数的参数
#统计缺失值个数
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)

两年前写的东西了,会逐步都发出来,有很多新函数暂时就不更新了 :(

 

 类似资料: