R語言提供了批量處理函數(shù)跋核,可以循環(huán)遍歷某個集合內(nèi)的所有或部分元素,以簡化操作叛买。
這些函數(shù)底層是通過C來實(shí)現(xiàn)的砂代,所以效率也比手工遍歷來的高效。
批量處理函數(shù)有很重要的apply族函數(shù):lapply sapply apply tapply mapply率挣。apply族函數(shù)是高效能計(jì)算的運(yùn)算向量化(Vectorization)實(shí)現(xiàn)方法之一刻伊,比起傳統(tǒng)的for,while常常能獲得更好的性能。
apply : 用于遍歷數(shù)組中的行或列椒功,并且使用指定函數(shù)來對其元素進(jìn)行處理捶箱。
lapply : 遍歷列表向量內(nèi)的每個元素,并且使用指定函數(shù)來對其元素進(jìn)行處理动漾。返回列表向量丁屎。
sapply : 與lapply基本相同,只是對返回結(jié)果進(jìn)行了簡化旱眯,返回的是普通的向量晨川。
mapply: 支持傳入兩個以上的列表。
tapply: 接入?yún)?shù)INDEX删豺,對數(shù)據(jù)分組進(jìn)行運(yùn)算共虑,就和SQL中的by group一樣。
(1)行或列遍歷操作函數(shù)apply
apply(X, MARGIN, FUN, ...)
參數(shù):
X: an array, including a matrix.
MARGIN: 1:行操作呀页; 2:列操作
FUN:函數(shù)名
用apply可以很方便地按行列求和/平均妈拌,其結(jié)果與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,sum)
[1] 22 26 30
apply(a,2,sum)
[1] 6 15 24 33
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
(2)列表(list)遍歷函數(shù)lapply
lapply(list, function, ...)
特點(diǎn):對每列進(jìn)行操作蓬蝶,非常適合數(shù)據(jù)框供炎;輸入的數(shù)據(jù)必須是list型渴逻。
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
a.df<-data.frame(a)
a
[,1] [,2] [,3] [,4]
[1,] 1 4 7 10
[2,] 2 5 8 11
[3,] 3 6 9 12
is.list(a.df)
[1] TRUE
str(a.df)
'data.frame': 3 obs. of 4 variables:
X2: int 4 5 6
X4: int 10 11 12
lapply(a.df, function(x) x+3)
X2
[1] 7 8 9
X4
[1] 13 14 15
lapply(a.df, function(x) sum(x)+3)
X2
[1] 18
X4
[1] 36
y<-lapply(a.df, function(x) sum(x)+3)
is.list(y)
[1] TRUE
names(y)
[1] "X1" "X2" "X3" "X4"
y
X2
[1] 18
X4
[1] 36
y[1]
X1
[1] 9
(3)sapply
sapply(list, function, ..., simplify)
simplify=F:返回值的類型是list,此時與lapply完全相同
simplify=T(默認(rèn)值):返回值的類型由計(jì)算結(jié)果定音诫,如果函數(shù)返回值長度為1惨奕,則sapply將list簡化為vector;
如果返回的列表中每個元素的長度都大于1且長度相同竭钝,那么sapply將其簡化位一個矩陣
yy<-sapply(a.df, function(x) x^2)
yy
X1 X2 X3 X4
[1,] 1 16 49 100
[2,] 4 25 64 121
[3,] 9 36 81 144
str(yy)
num [1:3, 1:4] 1 4 9 16 25 36 49 64 81 100 ...
- attr(*, "dimnames")=List of 2
..: chr [1:4] "X1" "X2" "X3" "X4"
str(y)
List of 4
X2: num 18
X4: num 36
yy<-sapply(a.df, function(x,y) x^2+y, y=3)
yy
X1 X2 X3 X4
[1,] 4 19 52 103
[2,] 7 28 67 124
[3,] 12 39 84 147> y1<-sapply(a.df, sum)
y1
X1 X2 X3 X4
6 15 24 33
str(y1)
Named int [1:4] 6 15 24 33
- attr(*, "names")= chr [1:4] "X1" "X2" "X3" "X4"
y1<-sapply(a.df, sum,simplify=F)
y1
$X1
[1] 6
$X2
[1] 15
$X3
[1] 24
$X4
[1] 33
str(y1)
List of 4
X2: int 15
X4: int 33
(4)mapply:mapply是sapply的多變量版本(multivariate sapply)梨撞,Apply a Function to Multiple List or Vector Arguments
mapply(FUN, ..., MoreArgs = NULL, SIMPLIFY = TRUE, USE.NAMES = TRUE)
mapply(function(x,y) x^y, c(1:5), c(1:5))
[1] 1 4 27 256 3125
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
mapply(sum, a[,1],a[,3],a[,4])
[1] 18 21 24
mapply(function(x,y,z) x^2+y+z, a[,1],a[,3],a[,4])
[1] 18 23 30
(5) tapply(X, INDEX, FUN = NULL, ..., simplify = TRUE)
x是需要處理的向量,INDEX是因子(因子列表)香罐,F(xiàn)UN是需要執(zhí)行的函數(shù)卧波,simplify指是否簡化輸入結(jié)果(考慮sapply對于lapply的簡化)
補(bǔ)充個因子函數(shù)gl,它可以很方便的產(chǎn)生因子庇茫,在方差分析中經(jīng)常會用到
gl(3,5) 3是因子水平數(shù)港粱,5是重復(fù)次數(shù)
[1] 1 1 1 1 1 2 2 2 2 2 3 3 3 3 3
Levels: 1 2 3
gl(3,1,15) 15是結(jié)果的總長度
[1] 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3
Levels: 1 2 3
df <- data.frame(year=kronecker(2001:2003, rep(1,4)), loc=c('beijing','beijing','shanghai','shanghai'), type=rep(c('A','B'),6), sale=rep(1:12))
df
year loc type sale
1 2001 beijing A 1
2 2001 beijing B 2
3 2001 shanghai A 3
4 2001 shanghai B 4
5 2002 beijing A 5
6 2002 beijing B 6
7 2002 shanghai A 7
8 2002 shanghai B 8
9 2003 beijing A 9
10 2003 beijing B 10
11 2003 shanghai A 11
12 2003 shanghai B 12
tapply(dfsale,df[,c('type','loc')],sum)
loc
type beijing shanghai
A 15 21
B 18 24