简介
批量处理函数有很重要的apply族函数:lapply sapply apply tapply mapply。这些函数底层通过C实现,效率比手工遍历高效。apply族函数是高效能计算的运算向量化(Vectorization)实现方法之一,比起传统的for,while常常能获得更好的性能。
- apply : 用于遍历数组中的行或列,并且使用指定函数来对其元素进行处理。
- lapply : 遍历列表向量内的每个元素,并且使用指定函数来对其元素进行处理。返回列表向量。
- sapply : 与lapply基本相同,只是对返回结果进行了简化,返回的是普通向量。
- mapply: 支持传入两个以上的列表。
- tapply: 接入参数INDEX,对数据分组进行运算,就和SQL中的by group一样。
apply函数
对矩阵、数据框、数组(二维、多维)等矩阵型数据,按行或列应用函数FUN进行循环计算,并以返回计算结果。
apply(X, MARGIN, FUN, …)
- X:数组、矩阵、数据框等矩阵型数据
- MARGIN:按行计算或按列计算,1表示按行,2表示按列
- FUN:自定义的调用函数,如mean/sum等(其结果与colMeans,colSums,rowMeans,rowSums是一样的)
> a<-matrix(1:12,c(3,4))
> a
[,1] [,2] [,3] [,4]
[1,] 1 4 7 10
[2,] 2 5 8 11
[3,] 3 6 9 12
> apply(a,1,function(x) sum(x)+2)
[1] 24 28 32
> apply(a,1,function(x) x^2)
[,1] [,2] [,3]
[1,] 1 4 9
[2,] 16 25 36
[3,] 49 64 81
[4,] 100 121 144
lapply函数
对列表、数据框按列进行循环,输入必须为列表(list),返回值为列表(list)。
lapply(X, FUN, …)
- X:列表、数据框
- FUN:自定义的调用函数
b<-list(x = 1:10, y = matrix(1:12, 3, 4))
$x
[1] 1 2 3 4 5 6 7 8 9 10
$y
[,1] [,2] [,3] [,4]
[1,] 1 4 7 10
[2,] 2 5 8 11
[3,] 3 6 9 12
lapply(b, sum) #求列表中各元素的和
$x
[1] 55
$y
[1] 78
> a=data.frame(matrix(1:12,c(3,4)))
> a
X1 X2 X3 X4
1 1 4 7 10
2 2 5 8 11
3 3 6 9 12
> names(a)
[1] "X1" "X2" "X3" "X4"
> str(a)
'data.frame': 3 obs. of 4 variables:
$ X1: int 1 2 3
$ X2: int 4 5 6
$ X3: int 7 8 9
$ X4: int 10 11 12
> lapply(a, function(x) x+3)
$X1
[1] 4 5 6
$X2
[1] 7 8 9
$X3
[1] 10 11 12
$X4
[1] 13 14 15
> a1 <- lapply(a, function(x) sum(x)+3)
> a1
$X1
[1] 9
$X2
[1] 18
$X3
[1] 27
$X4
[1] 36
> a1[1]
$X1
[1] 9
> a1[[1]]
[1] 9
sapply函数
类似于lapply函数,但输入为列表(list),返回值为向量。
sapply(X, FUN, …,simplify )
- X:列表、矩阵、数据框
- FUN:自定义的调用函数
- simplify=F:返回值的类型是list,此时与lapply完全相同
simplify=T(默认值):返回值的类型由计算结果定,如果函数返回值长度为1,则sapply将list简化为vector;如果返回的列表中每个元素的长度都大于1且长度相同,那么sapply将其简化位一个矩阵
> a=data.frame(matrix(1:12,c(3,4)))
> a #"list"
X1 X2 X3 X4
1 1 4 7 10
2 2 5 8 11
3 3 6 9 12
> str(a)
'data.frame': 3 obs. of 4 variables:
$ X1: int 1 2 3
$ X2: int 4 5 6
$ X3: int 7 8 9
$ X4: int 10 11 12
> a2 <- lapply(a, function(x) x+3)
> a2 #"list"
$X1
[1] 4 5 6
$X2
[1] 7 8 9
$X3
[1] 10 11 12
$X4
[1] 13 14 15
> str(a2)
List of 4
$ X1: num [1:3] 4 5 6
$ X2: num [1:3] 7 8 9
$ X3: num [1:3] 10 11 12
$ X4: num [1:3] 13 14 15
> a3 <- sapply(a, function(x) x^2)
> a3 #"numeric"
X1 X2 X3 X4
[1,] 1 16 49 100
[2,] 4 25 64 121
[3,] 9 36 81 144
> str(a3)
num [1:3, 1:4] 1 4 9 16 25 36 49 64 81 100 ...
- attr(*, "dimnames")=List of 2
..$ : NULL
..$ : chr [1:4] "X1" "X2" "X3" "X4"
> b<-list(x = 1:10, y = matrix(1:12, 3, 4))
> sapply(b, sum)
x y
55 78
sapply函数可提取列表中数据
y<-c("100-D","100-A","110-c","110-A")
z<-strsplit(y,"-")
sapply(z,"[",1) #提取列表第1个元素
sapply(z,"[",2) #提取列表中第2个元素
第一行:定义一个向量y
第二行:使用strsplit函数对向量y 按照“-”符号进行分割,得到一个列表z
第三行:使用sapply函数提取列表z的第1个和第2个位置元素,输出结果如下:
[1] "100" "100" "110" "110"
> sapply(z,"[",2) #提取列表中第2个元素
[1] "D" "A" "c" "A"
mapply函数
mapply是sapply的多变量版本(multivariate sapply)。
mapply(FUN, …, MoreArgs = NULL, SIMPLIFY = TRUE, USE.NAMES = TRUE)
> a <- mapply(function(x,y) x^y, c(1:5), c(1:5))
> a
[1] 1 4 27 256 3125
> mode(a)
[1] "numeric"
> str(a)
num [1:5] 1 4 27 256 3125
> names(a)
NULL
> b<-matrix(1:12,c(3,4),dimnames=list(c("a","b","c"),c("A","B","C","D")))
> b
A B C D
a 1 4 7 10
b 2 5 8 11
c 3 6 9 12
> mapply(sum, b[,1],b[,3],b[,4])
a b c
18 21 24
> mapply(sum,b[1,],b[2,],b[3,])
A B C D
6 15 24 33
tapply函数
将数据按照不同方式分组,生成类似列联表形式的数据结果。
tapply(X, INDEX, FUN = NULL, …, default = NA, simplify = TRUE)
- X:数组、矩阵、数据框等分割型数据向量
- INDEX:一个或多个因子的列表(因子列表),每个因子的长度都与x相同
- FUN: 自定义的调用函数
- simplify指是否简化输入结果(考虑sapply对于lapply的简化)
代码举例
manager <- c(1, 2, 3, 4, 5)
country <- c("US", "US", "UK", "UK", "UK")
gender <- c("M", "F", "F", "M", "F")
age <- c(32, 45, 25, 39, 99)
leadership <- data.frame(manager, country, gender, age)
tapply(leadership$age, leadership$country, mean) #求在不同country水平下的age的均值
tapply(leadership$age, list(leadership$country, leadership$gender), mean) #求在不同country和gender交叉水平下的age的均值, 输出得到矩阵数据
输出结果
UK US
54.33333 38.50000
F M
UK 62 39
US 45 32
转载:https://blog.csdn.net/fancy_koi/article/details/113852348
查看评论