apply ファミリーの関数には apply
のほかに tapply
mapply
lapply
sapply
などがある。行列あるいはリストに対して、一括して演算を行うときに利用する。
関数 | 働き |
apply(x,i,f) | 行列・データフレーム(x)に対して、各行(i = 1)または各列(i = 2)ごとに演算(f)を行う。 |
lapply(x,f) | リスト(x)の各要素に対して演算(f)を行う。実行結果をリスト型で返す。 |
sapply(x,f) | リスト(x)の各要素に対して演算(f)を行う。実行結果をベクトル型で返す。 |
apply
apply 関数の基本的な使い方
行列型またはデータフレーム型のデータに対して、各行または各列に対して、同種の演算を一括に行うときに apply
を利用する。apply
の 1 つ目の引数にはデータを代入する。2 つ目の引数には 1 または 2 を代入する。1 は各行を意味し、2 は各列を意味する。また、3 つ目の引数には適用したい演算(関数名)を与える。
x <- matrix(c(12.1, 3.44, 0.1, 3, 12, 33.1, 1.1, 23), nrow = 2)
x
## [,1] [,2] [,3] [,4]
## [1,] 12.10 0.1 12.0 1.1
## [2,] 3.44 3.0 33.1 23.0
# calculate totals
apply(x, 1, sum)
## [1] 25.30 62.54
# calculate averages
apply(x, 2, mean)
## [1] 7.77 1.55 22.55 12.05
上で用いた sum
や mean
などの関数は R に標準実装されている関数である。これを自作関数に置き換えることも可能である。例えば、以下の用にすると、i
には各行のデータが代入される。
x <- matrix(c(12.1, 3.44, 0.1, 3, 12, 33.1, 1.1, 23), nrow = 2)
# get the maximum numbers from each row
M <- apply(x, 1, function(y) {
# `y` contains data of the each row of `x`
m <- max(y)
return(m)
}
)
## [1] 12.1 33.1
# use for-loop instead of apply function
M <- NULL
for (j in 1:nrow(x)) {
y <- x[j, ]
m <- max(y)
M <- c(M, m)
}
M
## [1] 12.1 33.1
apply 関数に引数を与える方法
apply
に自作関数を適用させたい場合、時には外部から引数を与える必要がある。一般に、apply
関数は 3 つの引数を受けとるが、4 つ目以降に代入された引数は、自動的に 3 番目に指定した関数に引き渡される。
x <- c(1, 3, 5, 7)
y <- c(2, 4, 6, 8)
mat <- matrix(1:10, ncol = 2)
d <- apply(mat, 1, function(i, px = x, py = y) {
a <- i[1] + 2 * i[2]
# `px` is `x` in this apply function.
# `py` is `y` in this apply function.
b <- mean(px) * mean(py)
return(c(a, b))
}, x, y)
d
## [,1] [,2] [,3] [,4] [,5]
## [1,] 13 16 19 22 25
## [2,] 20 20 20 20 20
lapply
lapply
はリスト型に対して、何かを一括演算するときに利用する。リスト型のデータは、1、2、… のように番号付けられているため、行列のように行または列を指定しない。そのため、行列を指定しない分、引数は入力データと演算処理を行う関数の 2 つだけである。
x <- list(1:10,11:20,21:30)
x
## [[1]]
## [1] 1 2 3 4 5 6 7 8 9 10
## [[2]]
## [1] 11 12 13 14 15 16 17 18 19 20
## [[3]]
## [1] 21 22 23 24 25 26 27 28 29 30
lapply(x,sum)
## [[1]]
## [1] 55
## [[2]]
## [1] 155
## [[3]]
## [1] 255
sapply
lapply
と同じ使い方で、同じ機能を持つ。ただし、戻り値は lapply
ではリスト型であるのに対して、sapply
はベクトル型となる。
x <- list(1:10,11:20,21:30)
lapply(x, sum)
## [[1]]
## [1] 55
##
## [[2]]
## [1] 155
##
## [[3]]
## [1] 255
sapply(x, sum)
## [1] 55 155 255
as.numeric(lapply(x, sum))
## [1] 55 155 255