複数の行列の足し算をしたいです。 行列が2つであれば、行列A+行列Bで済みます。たくさんあってもこの方法でいいですが、気持ち悪いです。なにより大変です。 ということでいくつか考えたメモです。

# 複数の行列をリストで持つオブジェクトを作ります
set.seed(123)
N <- 100
m <- vector('list', N)
for(i in 1:N) m[[i]] <- matrix(rnorm(6), 2, 3)

方法

4つ考えました。

# for文で1つずつ足す。感覚的
for_loop <- function(data) {
  res <- data[[1]]
  for(i in 2:length(data)) {
    res <- res + data[[i]]
  }
  res
}
for_loop(m)
##           [,1]      [,2]     [,3]
## [1,] 10.581840  14.80878 4.219499
## [2,] -8.820872 -10.11387 2.389854
# 行列を1行にして足し、形を戻す
vec_sum <- function(data) {
  matrix(rowSums(sapply(data, as.vector)), nrow = nrow(data[[1]]), ncol = ncol(data[[1]]))
}
vec_sum(m)
##           [,1]      [,2]     [,3]
## [1,] 10.581840  14.80878 4.219499
## [2,] -8.820872 -10.11387 2.389854
# リストから3次元のarray形式としてapplyをかける
array_sum <- function(data) {
  data2 <- array(dim = c(nrow(data[[1]]), ncol(data[[1]]), length(data)))
  for(i in 1:length(data)) {
    data2[, , i] <- data[[i]]
  }
  apply(data2, 1:2, sum)
}
array_sum(m)
##           [,1]      [,2]     [,3]
## [1,] 10.581840  14.80878 4.219499
## [2,] -8.820872 -10.11387 2.389854
# Reduceで一発。気持ちいい
reduce <- function(data) {
  Reduce('+', data)
}
reduce(m)
##           [,1]      [,2]     [,3]
## [1,] 10.581840  14.80878 4.219499
## [2,] -8.820872 -10.11387 2.389854

速度

一応速さでも測りましょう

require(rbenchmark)
## Loading required package: rbenchmark
benchmark(replications = 10^5, for_loop(m), vec_sum(m), array_sum(m), reduce(m))
##           test replications elapsed relative user.self sys.self user.child
## 3 array_sum(m)       100000  31.284    2.861    30.410    0.098          0
## 1  for_loop(m)       100000  11.616    1.062    11.369    0.048          0
## 4    reduce(m)       100000  10.936    1.000    10.722    0.041          0
## 2   vec_sum(m)       100000  28.009    2.561    27.307    0.127          0
##   sys.child
## 3         0
## 1         0
## 4         0
## 2         0

コードとしてはReduceを使うのが気持ちいいですが、たいして遅くもないのでやっぱりfor文がわかりやすくて良さそうです。