Shinzi Katoh
Shinzi Katoh

Reputation: 291

cumulative sum of multiple matrices in r

Suppose that I have an array consisting of 3 matrices.

set.seed(1)
array1<-array(sample(1:50,18), dim=c(2,3,3))
, , 1
     [,1] [,2] [,3]
[1,]   14   28   10
[2,]   19   43   41
, , 2
     [,1] [,2] [,3]
[1,]   42   27    9
[2,]   29    3    7
, , 3
     [,1] [,2] [,3]
[1,]   44   48   25
[2,]   15   18   33

What I need to have is two matrix-wise cumulative matrices, one is the sum of first two matrices and the other is the sum of three matrices. Obviously, I can simply get them by calculating sum of the two matrices as below.

array1[,,1]+array1[,,2]
     [,1] [,2] [,3]
[1,]   56   55   19
[2,]   48   46   48

array1[,,1]+array1[,,2]+array1[,,3]
     [,1] [,2] [,3]
[1,]  100  103   44
[2,]   63   64   81

However, I'd like to know a way to generate the cumulative matrices with a simple function in case there are many matrices.

Thanks.

Upvotes: 2

Views: 633

Answers (2)

drsh
drsh

Reputation: 66

Just to add to akrun's approach for your specific example, the function form for creating and summing within the array would be:

set.seed(1)
SumMatrices<-function(beginSum,endSum,n){
matrixArray<-array(sample(1:50,6*n), dim=c(2,3,n)) 
#where 6 is the product of the first two dimensions - 2*3,
#and 1:50 are the limits of the random number generation
apply(matrixArray[,,beginSum:endSum], c(1,2), sum)
#beginSum and endSum are the matrices within the array you would
#like to sum
}
SumMatrices(1,2,3)

Of course, this can also be generalised so the user can set the matrices within the array to be any dimension they would like:

set.seed(1)
SumMatrices<-function(beginSum,endSum,x,y,n){
matrixArray<-array(sample(1:50,x*y*n), dim=c(x,y,n)) 
apply(matrixArray[,,beginSum:endSum], c(1,2), sum)
}
SumMatrices(1,2,2,3,3)

Hope this answers your question!

Upvotes: 2

akrun
akrun

Reputation: 887213

We can use apply with the MARGIN and get the sum

apply(array1[,,1:2], c(1,2), sum)
#     [,1] [,2] [,3]
#[1,]   56   55   19
#[2,]   48   46   48

apply(array1, c(1,2), sum)
#     [,1] [,2] [,3]
#[1,]  100  103   44
#[2,]   63   64   81

Or we specify the MARGIN=1 and get the rowSums

t(apply(array1[,, 1:2], 1, rowSums))
t(apply(array1, 1, rowSums))

Or another option is a for loop after initializing an output matrix ('r2')

r2 <- matrix(0, nrow = nrow(array1[,,1]), ncol = ncol(array1[,,1]))
for(j in seq(dim(array1)[3])){
     r2 <- r2 + array1[,,j]
 }
r2
#    [,1] [,2] [,3]
#[1,]  100  103   44
#[2,]   63   64   81

For the first case, instead of seq(dim(array1)[3]), use head(seq(dim(array1)[3]),2) in the for loop.

Upvotes: 2

Related Questions