apply familyの紹介
まとめ
- Rらしいコードを書くならapply family
- ベクトル、行列、データフレーム、リストに対して何か作用させるようなもの
- applyとtapplyは覚えて帰って損ないよ!!
apply familyって?
- lispのapplyのようなもの
- Rを使いこなす上では割けては通れない関数群
- Rはインタプリタ的なものなので、for文をそのまま回すと遅いことがある
- ベクトルを中心に考えるRとしては、Rらしいコードが書ける
で、applyファミリーって何?
- ベクトル、行列、データフレーム、リストに対して何か作用させるようなもの
種類
- apply
- tapply
- sapply
- lapply
- rapply
- mapply
例で説明
apply
> cars
> mean(cars$speed)
[1] 15.4
> mean(cars$dist)
[1] 42.98
一つ一つめんどくさい
- この例ならsummary(cars)とかでできる
- 自分で作った関数とかsummaryがやってくれないやつを一辺にやりたい
- 例えば、自分で平均と標準偏差を返す関数を作ったとか
- そういう時にapply関数
実例
> apply(cars,2,mean)
speed dist
15.40 42.98
mapply
- (複数個の)ベクトルのそれぞれの要素をある関数に適用させることができる関数
- RubyやPerlのmapと思ってもらえばいいです
> mapply(function(x,y){x+y},1:10,11:20)
[1] 12 14 16 18 20 22 24 26 28 30
> mapply(function(x){paste("R:",x,sep="")},1:10)
[1] "R:1" "R:2" "R:3" "R:4" "R:5" "R:6" "R:7" "R:8" "R:9" "R:10"
mapplyを使わないでやることもできる
> paste("R:",1:10,sep="")
[1] "R:1" "R:2" "R:3" "R:4" "R:5" "R:6" "R:7" "R:8" "R:9" "R:10"
ちなみにMap関数というのもあるよ
> Map(function(x){paste("R:",x,sep="")},1:10)
[[1]]
[1] "R:1"
[[2]]
[1] "R:2"
[[3]]
[1] "R:3"
[[4]]
[1] "R:4"
[[5]]
[1] "R:5"
[[6]]
[1] "R:6"
[[7]]
[1] "R:7"
[[8]]
[1] "R:8"
[[9]]
[1] "R:9"
[[10]]
[1] "R:10"
lapplyとsapply
- 本質的には同じような働きをする関数
- 返す結果がリストか、ベクトル(行列)かという違いくらい
lapply
- リストに対して、ある関数をそれぞれ適用させるための関数
- データフレームっぽいのならapplyでいい
- 長さが整っていないものならlapplyかsapplyを使いましょう
- lapplyは返す結果がlist
> a <- 1:10
> b <- letters[1:26]
> x <- list(a,b)
> lapply(x,summary)
[[1]]
Min. 1st Qu. Median Mean 3rd Qu. Max.
1.00 3.25 5.50 5.50 7.75 10.00
[[2]]
Length Class Mode
26 character character
sapply
- lapplyの返す結果がベクトルのやつ
- 返ってきた結果を使いまわすんだったら、こっちのほうが使い易いかもしれない
> x <- list(a = 1:10, beta = exp(-3:3), logic = c(TRUE,FALSE,TRUE,FALSE))
> sapply(x, mean)
a beta logic
5.500000 4.535125 0.500000
tapply
- 因子とか層別で分析したいときに重宝する関数
- こいつはapplyとtapplyくらいは覚えて帰って損しないと思うよ
> library(MASS)
> attach(quine)
> tapply(Days,Age,mean)
F0 F1 F2 F3
14.85185 11.15217 21.05000 19.60606
> tapply(Days,list(Sex,Age),mean)
F0 F1 F2 F3
F 18.70000 12.96875 18.42105 14.00000
M 12.58824 7.00000 23.42857 27.21429
> tapply(Days,list(Sex,Age),mean)
F0 F1 F2 F3
F 18.70000 12.96875 18.42105 14.00000
M 12.58824 7.00000 23.42857 27.21429
rapply
- listに対して再帰的に作用する関数
- データ解析をする時はそんなに使わないかも…?
- ネストしたリストに対して、それぞれの要素の絶対値を返す例
> list(-5:5,rep(0:1,3),list(10:-10))
[[1]]
[1] -5 -4 -3 -2 -1 0 1 2 3 4 5
[[2]]
[1] 0 1 0 1 0 1
[[3]]
[[3]][[1]]
[1] 10 9 8 7 6 5 4 3 2 1 0 -1 -2 -3 -4 -5 -6 -7 -8
[20] -9 -10
> rapply(list(-5:5,rep(0:1,3),list(10:1)),abs,how="list")
[[1]]
[1] 5 4 3 2 1 0 1 2 3 4 5
[[2]]
[1] 0 1 0 1 0 1
[[3]]
[[3]][[1]]
[1] 10 9 8 7 6 5 4 3 2 1
functionのところは任意の関数が書けるよ
- 2で割って余りが0じゃなかったら"fuga"に置換
> rapply(list(-5:5,rep(0:1,3),list(10:1)),function(x){ifelse(x%%2==0,x,"fuga")},how="list")
[[1]]
[1] "fuga" "-4" "fuga" "-2" "fuga" "0" "fuga" "2" "fuga" "4"
[11] "fuga"
[[2]]
[1] "0" "fuga" "0" "fuga" "0" "fuga"
[[3]]
[[3]][[1]]
[1] "10" "fuga" "8" "fuga" "6" "fuga" "4" "fuga" "2" "fuga"
まとめ
- Rらしいコードを書くならapply family
- ベクトル、行列、データフレーム、リストに対して何か作用させるようなもの
- applyとtapplyは覚えて帰って損ないよ!!