69

I have a list where each element is a 5*5 matrix. Eg

[[1]]   
           V1          V2          V3          V4          V5      
      [1,]   0.000000   46.973700   21.453500  338.547000   10.401600 
      [2,]  43.020500    0.000000  130.652000  840.526000   56.363700 
      [3,]  12.605600  173.238000    0.000000  642.075000   19.628100 
      [4,] 217.946000  626.368000  481.329000    0.000000  642.341000 
      [5,] 217.946000  626.368000  481.329000    0.000000  642.341000 
[[2]]   
           V1          V2          V3          V4          V5      
      [1,]   0.000000   47.973700   21.453500  338.547000   10.401600 
      [2,]  143.020500    0.000000  130.652000  840.526000   56.363700 
      [3,]  312.605600  17.238000    0.000000  642.075000   19.628100 
      [4,]  17.946000  126.368000  481.329000    0.000000  642.341000
      [5,] 217.946000  626.368000  481.329000    0.000000  642.341000  
...

How can I use an apply-like function to sum matrix [1] to [n], and return a 5*5 matrix as a result (each element is a sum of the corresponding elements in each of the matrix in the list) ?

TooTone
  • 7,129
  • 5
  • 34
  • 60
Seen
  • 4,054
  • 4
  • 37
  • 46
  • I suggest you edit your post to give a reproducible example and make clearer what you're after. An example of what your final result would like like would also be helpful. In it's current state it will likely be closed. – Tyler Rinker Jul 25 '12 at 02:08
  • Thanks for your suggestion. My post has been edited. – Seen Jul 25 '12 at 02:14
  • Are you summing a list of 5 * 5 matrices? to give a 5 *5 matrix? – mnel Jul 25 '12 at 02:25

3 Answers3

120

Use Reduce.

## dummy data

.list <- list(matrix(1:25, ncol = 5), matrix(1:25, ncol = 5))

Reduce('+', .list)
##       [,1] [,2] [,3] [,4] [,5]
## [1,]    2   12   22   32   42
## [2,]    4   14   24   34   44
## [3,]    6   16   26   36   46
## [4,]    8   18   28   38   48
## [5,]   10   20   30   40   50
mnel
  • 113,303
  • 27
  • 265
  • 254
15

I think @mnel's answer is the more efficient but this is another approach:

apply(simplify2array(.list), c(1,2), sum)

    [,1] [,2] [,3] [,4] [,5]
[1,]    2   12   22   32   42
[2,]    4   14   24   34   44
[3,]    6   16   26   36   46
[4,]    8   18   28   38   48
[5,]   10   20   30   40   50
Jilber Urbina
  • 58,147
  • 10
  • 114
  • 138
5

You could you do.call with some monkeying around but it loses its eloquence:

.list <- list(matrix(1:25, ncol=5), matrix(1:25,ncol=5), matrix(1:25,ncol=5))

x <- .list[[1]]
lapply(seq_along(.list)[-1], function(i){
    x <<- do.call("+", list(x, .list[[i]]))
})
x
Tyler Rinker
  • 108,132
  • 65
  • 322
  • 519
  • 1
    But, then you don't need `do.call`; you could have `x <<- x + .list[[i]]` inside your `lapply`. – GSee Jul 25 '12 at 03:06
  • 1
    very true. `Reduce` is much more eloquent though on a bunch of matrices the `lapply` approach may be faster (sometimes the Higher Order Functions suffer speed issues). – Tyler Rinker Jul 25 '12 at 03:13