R: how do apply the sum function in a list?

Viewed 590

I am having a problem with summing the rows of my matrices. I have a list formed by 30 matrices

Matrix<-matrix(1:45, ncol=9)
List<-list(lapply(seq_len(30), function(X) Matrix))

The idea is to create 30 matrices size 5*3. Firstly, I need to sum some columns, 1:3 4:6 7:9, such that the result will be the following:

     [,1] [,2] [,3] 
[1,]    18    63   108   
[2,]    21    66   111   
[3,]    34    69   114   
[4,]    47    72   117   
[5,]    30    75   120   

I am trying to get this matrix using this code:

Y<-lapply(List, function(x) rowSums(x[, 1:3]))

But, it only allows me to sum the 3 firsts columns.

After this, I need to sum the list and obtain only one matrix(5*3). I think that the command final<-reduce(Y,+) could help.

540 1890 3240
630 1980 3330
1020 2070 3420
1410 2160 3510
900 2250 3600

Thank you for your help

2 Answers

You need to find someway to group your columns by threes, for example:

grp = (1:ncol(Matrix) -1) %/% 3

or if you know the dimensions:

grp  = rep(0:2,each=3)

To do rowSums in columns of threes, we can do this with a function:

SumCols = function(M,col_grp){
sapply(unique(col_grp),function(i)rowSums(M[,col_grp==i]))
}
SumCols(Matrix,grp)

     [,1] [,2] [,3]
[1,]   18   63  108
[2,]   21   66  111
[3,]   24   69  114
[4,]   27   72  117
[5,]   30   75  120

So put this inside your List of matrices,

Reduce("+",lapply(List[[1]],SumCols,grp))

     [,1] [,2] [,3]
[1,]  540 1890 3240
[2,]  630 1980 3330
[3,]  720 2070 3420
[4,]  810 2160 3510
[5,]  900 2250 3600

Here is another base R solution

out <- Reduce(`+`,Map(function(x) do.call(cbind,Map(rowSums, split.default(data.frame(x),ceiling(seq(ncol(x))/3)))),List[[1]]))

such that

> out
       0    1    2
[1,] 540 1890 3240
[2,] 630 1980 3330
[3,] 720 2070 3420
[4,] 810 2160 3510
[5,] 900 2250 3600
Related