在R的世界裡,for迴圈是幾乎所以R programmer都要盡量避免的,因為for迴圈真的很容易拖慢速度!
apply系列的函數可以把運算向量化(vectorization),讓程式
簡潔又
快速喔!!!
並且可以和還在用for迴圈的新手們炫耀自己的功力。
先來看看Demo的資料,都是R內建的
> library(datasets)
> head(cars)
speed dist
1 4 2
2 4 10
3 7 4
4 7 22
5 8 16
6 9 10
> head(airquality)
Ozone Solar.R Wind Temp Month Day
1 41 190 7.4 67 5 1
2 36 118 8.0 72 5 2
3 12 149 12.6 74 5 3
4 18 313 11.5 62 5 4
5 NA NA 14.3 56 5 5
6 28 NA 14.9 66 5 6
1. apply(資料名稱,計算方向,套用函數)
apply算是基本款的,但是就已經蠻強大的了
其中計算方向比較需要注意:
1 表示逐列
2 表示逐行
EX: 用apply函數來計算demo資料cars中不同欄位的平均數或者檢查資料格式,通通一行搞定!
> apply(cars,2,mean)
speed dist
15.40 42.98
> apply(cars,2,class)
speed dist
"numeric" "numeric"
2. tapply(資料$欄位,分層欄位,套用函數)
個人認為tapply還蠻好用的,尤其是要做分層的時候,功能就像是SQL語法的group by
EX: 我們可以用它來計算demo資料airquality中不同月份(Month)的最大風速(Wind)
> tapply(airquality$Wind, airquality$Month,max)
5 6 7 8 9
20.1 20.7 14.9 15.5 16.6
3. sapply(列表或向量,套用函數)
是作用在列表(list)或是向量(vector)上面的
EX: 把向量a通通取絕對值!
> sapply(-4:4,abs)
[1] 4 3 2 1 0 1 2 3 4
> a<- -4:4
> a
[1] -4 -3 -2 -1 0 1 2 3 4
或者把a這個list裡面的東東通通取平均
> a=list(a=c(1,2,3),b=c(2,3,4),c=c(3,4,5))
> a
$a
[1] 1 2 3
$b
[1] 2 3 4
$c
[1] 3 4 5
> sapply(a,mean)
a b c
2 3 4
4. mapply(函數,函數引數)
mapply其實就是sapply的多重版,可以放數多個函數引述
EX: 由N(0,1)中做五次抽樣,第一次抽一個樣本,第二次抽兩個樣本,...第五次抽五個樣本
> mapply(rnorm, n=1:7, mean=0, sd=1)
[[1]]
[1] -2.112067
[[2]]
[1] 0.7254029 -1.2384776
[[3]]
[1] 0.8083143 -1.6875636 0.6863660
[[4]]
[1] 2.0391266 0.2182393 -0.6225456 0.4714035
[[5]]
[1] 1.0811637 0.1209754 1.1659376 0.5173664 0.1244459
5. lapply(列表或向量,套用函數)
傳回列表(list)的apply函數
EX: 向量a中每個元素都+1並存在列表(list)裡
> > a <-1:4> a
[1] 1 2 3 4
> lapply(a,function(x) x+1)
[[1]]
[1] 2
[[2]]
[1] 3
[[3]]
[1] 4
[[4]]
[1] 5
6. rapply(列表或向量,套用函數)
針對嵌套列表(nested list就是,list中又有list的東東)的apply函數
how選項可以決定要不要針對各list裡的value
EX: 加總(how="unlist")
> a<- list(x1=1:5,x2=2:7)
> b<- list(x1=7:5,x2=0:7)
> rapply(list(a,b),sum,how="unlist")
x1 x2 x1 x2
15 27 18 28
EX: 加總(how="list")
> rapply(list(a,b),sum,how="list")
[[1]]
[[1]]$x1
[1] 15
[[1]]$x2
[1] 27
[[2]]
[[2]]$x1
[1] 18
[[2]]$x2
[1] 28