R語言學習筆記之apply、lapply、sapply、mapply、tapply函式詳解
轉載於:http://blog.csdn.net/wa2003/article/details/45887055
R語言提供了批量處理函式,可以迴圈遍歷某個集合內的所有或部分元素,以簡化操作。
這些函式底層是通過C來實現的,所以效率也比手工遍歷來的高效。
批量處理函式有很重要的apply族函式:lapply sapply apply tapply mapply。apply族函式是高效能計算的運算向量化(Vectorization)實現方法之一,比起傳統的for,while常常能獲得更好的效能。
apply : 用於遍歷陣列中的行或列,並且使用指定函式來對其元素進行處理。
lapply : 遍歷列表向量內的每個元素,並且使用指定函式來對其元素進行處理。返回列表向量。
sapply : 與lapply基本相同,只是對返回結果進行了簡化,返回的是普通的向量。
mapply: 支援傳入兩個以上的列表。
tapply: 接入引數INDEX,對資料分組進行運算,就和SQL中的by group一樣。
(1)行或列遍歷操作函式apply
apply(X, MARGIN, FUN, ...)
引數:
X: an array, including a matrix.
MARGIN: 1:行操作; 2:列操作
FUN:函式名
用apply可以很方便地按行列求和/平均,其結果與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)遍歷函式lapply
lapply(list, function, ...)特點:對每列進行操作,非常適合資料框;輸入的資料必須是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:
$ X1: int 1 2 3
$ X2: int 4 5 6
$ X3: int 7 8 9
$ X4: int 10 11 12
> lapply(a.df, function(x) x+3)
$X1
[1] 4 5 6
$X2
[1] 7 8 9
$X3
[1] 10 11 12
$X4
[1] 13 14 15
> lapply(a.df, function(x) sum(x)+3)
$X1
[1] 9
$X2
[1] 18
$X3
[1] 27
$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
$X1
[1] 9
$X2
[1] 18
$X3
[1] 27
$X4
[1] 36
> y[1]
$X1
[1] 9
> y[[1]]
[1] 9
> y$X1
[1] 9
(3)sapply
sapply(list, function, ..., simplify)
simplify=F:返回值的型別是list,此時與lapply完全相同
simplify=T(預設值):返回值的型別由計算結果定,如果函式返回值長度為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
..$ : NULL
..$ : chr [1:4] "X1" "X2" "X3" "X4"
> str(y)
List of 4
$ X1: num 9
$ X2: num 18
$ X3: num 27
$ 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
$ X1: int 6
$ X2: int 15
$ X3: int 24
$ 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是因子(因子列表),FUN是需要執行的函式,simplify指是否簡化輸入結果(考慮sapply對於lapply的簡化)
補充個因子函式gl,它可以很方便的產生因子,在方差分析中經常會用到
> gl(3,5) 3是因子水平數,5是重複次數
[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是結果的總長度
[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(df$sale,df[,c('year','loc')],sum)
loc
year beijing shanghai
2001 3 7
2002 11 15
2003 19 23
> tapply(df$sale,df[,c('type','loc')],sum)
loc
type beijing shanghai
A 15 21
B 18 24