R语言apply系列函数的基本作用是对数组(array,可以是多维)或者列表(list)按照元素或元素构成的子集合进行迭代,并将当前元素或子集合作为参数调用某个指定函数。vector是一维的array,dataframe可以看作特殊的list。
作用目标 |
在每个元素上应用 |
在子集合上应用 |
array |
apply |
tapply |
list |
lapply (...) |
by |
其中 lapply(...) 为一族函数,包括简化版: sapply,递归版: rapply。其中sapply又可分为可设置返回值模板vapply和多变量版mapply。另外vector比较特殊,vector是一维的array,但是却不全是和array使用相同的函数。在按元素迭代的情况下,使用和list一样的 lapply 函数;而在按子集合迭代的情况下, tapply 和 by 都能用,只是返回值形式不同。
1. apply函数
在array上,沿margin方向,依次调用 FUN,返回结果通常为Array类型,如果返回值的向量长度不等,则返回List对象。margin表示数组引用的第几维下标(即array[index1, index2, ...]中的第几个index),margin = 1表示行,2表示列,c(1,2) 表示行和列。
– 举例1:
# 二维矩阵对象
x <- cbind(x1 = 3, x2 = c(4:1, 2:5))
dimnames(x)[[1]] <- letters[1:8]
apply(x, 2, mean, trim = .2)
apply(x, 1, mean, trim = .2)
apply(x, 2, sort)
– 举例2:
#三维数组对象,数据向量中的值被赋给数组中的值时,将遵循“主列顺序”,即第一个下标变化最快,最后的下表变化最慢。
z <- array(1:24, dim = 2:4)
apply(z, 3, mean)
apply(z, 1:2, function(x) seq_len(max(x)))
apply(z, 3, function(x) seq_len(max(x)))
注: 虽然vector是一维的array,但是不能使用apply,array只能用在二维及以上的array上,因为apply要求dim(X)的值必需是正数,vector对象的dim值为NULL。
2. tapply函数
按 indices 中的值分组,把相同值对应下标的array中的元素形成一个集合,应用到 FUN 。类似于group by indices的操作。当simplify = TRUE(默认)时,如果 FUN 返回的是一个值, tapply 返回Array,空值用NULL表示;若 FUN 返回多个值, tapply 返回list,空值使用NA表示。当simplify = FALSE时,tapply 都返回list 对象。 Array或list的长度和 indices 中不同值的个数相等。
当 FUN 为 NULL 的时候,返回一个长度和array中元素个数相等的vector,指示分组的结果,vector中相等的元素所对应的下标属于同一组。例如,返回c(1, 2, 1, 3, 2), 表示根据传入的 indices ,第1、3个元素作为一组,第2、5个元素作为一组,第4个元素作为一组。
– 举例1:
#tapply应用于vector
height <- c(174, 165, 180, 171, 160)
sex<-c("F","F","M","F","M")
#返回vector
tapply(height, sex, mean)
#返回list
tapply(height, sex, mean, simplify = F)
#因为函数fivenum返回多值,即使simplify = TRUE,也是返回list对象
tapply(height, sex, fivenum)
– 举例2:
#tapply应用于matrix