1、apply函数:
这个函数的使用格式为:apply(X,MARGIN, FUN, ...)。它应用的数据类型是数组或矩阵,返回值类型由FUN函数结果的长度确定。
X参数为数组或矩阵;MARGIN为要应用计算函数的边/维,MARGIN=1为第一维(行),2为第二维(列),...;FUN为要应用的计算函数,后面可以加FUN的有名参数。比如,要按行或列计算数组a的标准差就可以这样:
1. > apply(a, MARGIN=1, FUN=sd)
2. [1] 1 1 1
3. > apply(a, MARGIN=2, FUN=sd)
4. [1] 0 0 0
MARGIN的长度可以不是1(多维应用),如果长度等于X的维数,应用到FUN函数的数据就只有一个值,结果没什么意义,甚至函数会获得无效值:
1. > apply(b, MARGIN=3, FUN=sum)
2. [1] 9 18 27
3. > apply(b, MARGIN=1:2, FUN=sum)
4. [,1] [,2] [,3]
5. [1,] 6 6 6
6. [2,] 6 6 6
7. [3,] 6 6 6
8. > apply(a, MARGIN=1:2, FUN=sd)
9. [,1] [,2] [,3]
10.[1,] NA NA NA
11.[2,] NA NA NA
12.[3,] NA NA NA
上面我们使用的sd、sum或mean函数的返回值的向量长度都是1(每一次单独计算),apply函数结果的维数与MARGIN的向量长度相同;如果FUN函数返回值的长度不是1而是每次都为n,apply函数的结果是维度为c(n, dim(X)[MARGIN]):
1. > a
2. [,1] [,2] [,3]
3. [1,] 1 2 3
4. [2,] 1 2 3
5. [3,] 1 2 3
6. > apply(a, MARGIN=1, FUN=quantile, probs=seq(0,1, 0.25))
7. [,1] [,2] [,3]
8. 0% 1.0 1.0 1.0
9. 25% 1.5 1.5 1.5
10.50% 2.0 2.0 2.0
11.75% 2.5 2.5 2.5
12.100% 3.0 3.0 3.0
13.> apply(a, MARGIN=2, FUN=quantile, probs=seq(0,1, 0.25))
14. [,1] [,2] [,3]
15.0% 1 2 3
16.25% 1 2 3
17.50% 1 2 3
18.75% 1 2 3
19.100% 1 2 3
如果FUN函数返回值的长度不一样,情况就复杂了,apply函数的结果会是列表。
2、lapply、sapply和vapply函数:
这几个函数是一套,前两个参数都为X和FUN,其他参数在R的函数帮助文档里有相信介绍。它们应用的数据类型都是列表,对每一个列表元素应用FUN函数,但返回值类型不大一样。lappy是最基本的原型函数,sapply和vapply都是lapply的改进版。
2.1 lapply返回的结果为列表,长度与X相同
1. > scores <- list(YuWen=c(80,88,94,70), ShuXue=c(99,87,100,68,77))
2. > lapply(scores, mean)
3. $YuWen
4. [1] 83
5.
6. $ShuXue
7. [1] 86.2
8.
9. > lapply(scores, quantile, probs=c(0.5,0.7,0.9))
10.$YuWen
11. 50% 70% 90%
12.84.0 88.6 92.2
13.
14.$ShuXue
15. 50% 70% 90%
16.87.0 96.6 99.6
2.2 sapply返回的结果比较“友好”,如果结果很整齐,就会得到向量或矩阵或数组
sapply是simplify了的lapply,所谓的simplify,是指对结果的数据结构进行了simplify,方便后续处理。
1. > sapply(scores, mean)
2. YuWen ShuXue
3. 83.0 86.2
4. > sapply(scores, quantile, probs=c(0.5,0.7,0.9))
5. YuWen ShuXue
6. 50% 84.0 87.0
7. 70% 88.6 96.6
8. 90% 92.2 99.6
2.3 vapply函数:对返回结果(value)进行类型检查的sapply
虽然sapply的返回值比lapply好多了,但可预测性还是不好,如果是大规模的数据处理,后续的类型判断工作会很麻烦而且很费时。vapply增加的FUN.VALUE参数可以直接对返回值类型进行检查,这样的好处是不仅运算速度快,而且程序运算更安全(因为结果可控)。下面代码的rt.value变量设置返回值长度和类型,如果FUN函数获得的结果和rt.value设置的不一致(长度和类型)都会出错:
1. > probs <- c(1:3/4)
2. > rt.value <- c(0,0,0) #设置返回值为3个数字
3. > vapply(scores, quantile, FUN.VALUE=rt.value, probsprobs=probs)
4. YuWen ShuXue
5. 25% 77.5 77
6. 50% 84.0 87
7. 75% 89.5 99
8. > probs <- c(1:4/4)
9. > vapply(scores, quantile, FUN.VALUE=rt.value, probsprobs=probs)
错误于vapply(scores,quantile, FUN.VALUE = rt.value, probs = probs) :
值的长度必需为3,
但FUN(X[[1]])结果的长度却是4
1. > rt.value <- c(0,0,0,0) #返回值类型为4个数字
2. > vapply(scores, quantile, FUN.VALUE=rt.value, probsprobs=probs)
3. YuWen ShuXue
4. 25% 77.5 77
5. 50% 84.0 87
6. 75% 89.5 99
7. 100% 94.0 100
8. > rt.value <- c(0,0,0,'') #设置返回值为3个数字和1个字符串
9. > vapply(scores, quantile, FUN.VALUE=rt.value, probsprobs=probs)
错误于vapply(scores,quantile, FUN.VALUE = rt.value, probs = probs) :
值的种类必需是'character',
但FUN(X[[1]])结果的种类却是'double'
FUN.VALUE为必需参数。