作者:吴健
众所周知,当我们利用R语言处理大型数据集时,for循环语句的运算效率非常低。因此在实际应用中,数据处理人员常常利用apply族函数替代for循环以便于在一定程度上提升R语言数据处理速度,除此之外,该方法还可以在一定程度上简化代码。虽然该方法非常有用,但是当你面对复杂的情形时,你需要灵活运用该函数。基于此,本文详细介绍apply族函数的应用。
apply族函数包括apply(), lapply(), sapply(), vapply(),mapply(),rapply(), tapply()。在实际应用中,常常需要数据处理人员依据不同数据结构及数据处理目的采用不同apply族函数,下文将对apply族函数进行逐一介绍。
1. apply()函数
apply函数只能用于处理矩阵类型的数据,也就是说所有的数据必须是同一类型。因此要使用apply函数的话,需要将数据类型转换成矩阵类型。
--------------------------------------------------------------------------
apply(X, MARGIN, FUN, …)
X: 表示数组或矩阵
MARGIN:表示以行为单位进行计算还是以列为单位:1表示以行为单位;2表示以列为单位;c(1,2)表示同时以行和列为单位进行计算。
FUN:在行或者列上进行运算的函数。
...:运算函数的参数
--------------------------------------------------------------------------
例:
x <- matrix(rnorm(30), nrow=5, ncol=6)
dimnames(x)[[1]] <- letters[1:5]
dimnames(x)[[2]] <- letters[1:6]#创建数据集
apply(x, 2, mean, trim = .2)#以列为单位计算截尾平均值
col.sums <- apply(x, 2, sum)#以列为单位求和
col.sums#输出结果
row.sums <- apply(x, 1, sum)#以行为单位求和
row.sums#输出结果
结果:
2. lapply()函数和sapply()函数
lapply和sapply函数可以用于处理列表数据和向量数据(vector/list)。lapply函数得到处理得到的数据类型是列表,而sapply函数得到处理的数据类型是向量。这两个函数除了在返回值类型不同外,其他方面基本完全一样。
--------------------------------------------------------------------------
lapply(X, FUN, …)
sapply(X, FUN, ..., simplify = TRUE, USE.NAMES = TRUE)
X: 表示列表或者向量
FUN:在行或者列上进行运算的函数。
...:运算函数的参数
simplify:逻辑值或者字符,用来确定返回值的类型:TRUE表示返回向量或矩阵;simply = "array"返回数组
USE.NAMES:确定结果的名字。
--------------------------------------------------------------------------
例:
lapply
A <- matrix(c(1:9), nrow=3, ncol=3)
B <- matrix(c(4:15), nrow=4, ncol=3)
C <- matrix(rep(seq(8,10),2), nrow=3)
data <- list(A=A, B=B, C=C)#创建数据集
lapply(data, “[“, ,2)#提取列表中每一部分第二列的元素
lapply(data, “[“, 1,)#提取列表中每一部分第一行的元素
lapply(data, sum)#对列表每一部分求和
sapply
sapply(data, “[“, 2, 1)#提取列表每一部分第二行第一列的数,并以向量形式返回
sapply(data, “[“, 2, 1, simplify=F)#提取列表每一部分第二行第一列的数,并以列表形式返回
3. vapply()函数
vapply函数类似于sapply函数,其主要区别为vapply函数可预先指定返回值的类型和名称。
--------------------------------------------------------------------------
vapply(X, FUN, FUN.VALUE, ..., USE.NAMES = TRUE)
X: 表示列表或者向量
FUN:在行或者列上进行运算的函数。
FUN.VALUE:指定返回值的类型和名称
USE.NAMES:确定结果的名字。
--------------------------------------------------------------------------
例:
i39 <- sapply(3:9, seq) # 生成数据
sapply(i39, fivenum)#sapply计算每一个列表的分位数
vapply(i39, fivenum,#vapply计算每一个列表的分位数
c(Min. = 0, “1st Qu.” = 0, Median = 0, “3rd Qu.” = 0, Max. = 0))
结果:
4. mapply()函数
mapply函数主要是对多个列表或者向量参数使用函数。
--------------------------------------------------------------------------
mapply(FUN, ..., MoreArgs = NULL, SIMPLIFY = TRUE, USE.NAMES = TRUE)
FUN:在行或者列上进行运算的函数。
MoreArgs:FUN函数的其它参数。
simplify:逻辑值或者字符,用来确定返回值的类型。
USE.NAMES:确定结果的名字。
--------------------------------------------------------------------------
例:
mapply(rep, 1:4, 4:1)
mapply(rep, times = 1:4, x = 4:1)
mapply(rep, times = 1:4, MoreArgs = list(x = 42))
mapply(function(x, y) seq_len(x) + y,
c(a = 1, b = 2, c = 3),
c(A = 10, B = 0, C = -10))
结果:
5. rapply()函数
rapply函数是lapply函数的循环版本。
--------------------------------------------------------------------------
rapply(object, f, classes = "ANY", deflt = NULL, how = c("unlist", "replace", "list"), ...)
object:列表
f:只有一个参数的函数。
classes:表示类名的字符型向量。
deflt:默认结果(如果how="replace"参数没用)
how:匹配三种可能参数,分别为unlist, replace, list。具体三种参数的作用,可以结合代码修改相应参数值,看输出结果的变化来理解参数的作用。
...:函数f的额外参数
--------------------------------------------------------------------------
例:
X <- list(list(a = pi, b = list(c = 1:1)), d = “a test”)
rapply(X, function(x) x, how = “replace”)
rapply(X, sqrt, classes = “numeric”, how = “replace”)
rapply(X, nchar, classes = “character”,
deflt = as.integer(NA), how = “list”)
rapply(X, nchar, classes = “character”,
deflt = as.integer(NA), how = “unlist”)
rapply(X, nchar, classes = “character”, how = “unlist”)
rapply(X, log, classes = “numeric”, how = “replace”, base = 2)
6. tapply()函数
它通常会有三个参数,第一个参数代表数据,第二个参数表示如何对数据进行分组操作,第三个参数指定每一个分组内应用什么函数。也就是说tapply函数就是把数据按照一定方式分成不同的组,再在每一组数据内进行某种运算。
--------------------------------------------------------------------------
tapply(X, INDEX, FUN = NULL, ..., default = NA, simplify = TRUE)
X:被计算的向量值。
INDEX:分类因子。
FUN:分组计算的函数。
...:函数的额外参数
simplify:逻辑值或者字符,用来确定返回值的类型。
--------------------------------------------------------------------------
例1:
install.packages(“HSAUR2”)#安装程序包
library(HSAUR2)#加载程序包
data(CHFLS)#加载数据
head(CHFLS)#查看数据前六列
str(CHFLS)#查看数据属性
tapply(CHFLS$R_income, CHFLS$R_health, mean)#分类计算平均值
例2:
n <- 17; fac <- factor(rep_len(1:3, n), levels = 1:5)
table(fac)
tapply(1:n, fac, sum)
tapply(1:n, fac, sum, default = 0) # maybe more desirable
tapply(1:n, fac, sum, simplify = FALSE)
注:具体参数的作用,可以结合代码修改相应参数值,看输出结果的变化来理解参数的作用。