1

So I have taken a look at this question posted before which was used for summing every 2 values in each row in a matrix. Here is the link: sum specific columns among rows. I also took a look at another question here: R Sum every k columns in matrix which is more similiar to mine. I could not get the solution in this case to work. Here is the code that I am working with...

y <- matrix(1:27, nrow = 3)
y

m1 <- as.matrix(y)
n <- 3
dim(m1) <- c(nrow(m1)/n, ncol(m1), n)
res <- matrix(rowSums(apply(m1, 1, I)), ncol=n)
identical(res[1,],rowSums(y[1:3,]))


sapply(split.default(y, 0:(length(y)-1) %/% 3), rowSums)

I just get an error message when applying this. The desired output is a matrix with the following values:

      [,1] [,2] [,3]
[1,]   12   39   66
[2,]   15   42   69
[3,]   18   45   72
Community
  • 1
  • 1
Adam Warner
  • 1,334
  • 2
  • 14
  • 30

3 Answers3

2

To sum consecutive sets of n elements from each row, you just need to write a function that does the summing and apply it to each row:

n <- 3
t(apply(y, 1, function(x) tapply(x, ceiling(seq_along(x)/n), sum)))
#       1  2  3
# [1,] 12 39 66
# [2,] 15 42 69
# [3,] 18 45 72
josliber
  • 43,891
  • 12
  • 98
  • 133
  • An option without `apply` could be `matrix(tapply(t(y), ceiling(seq_along(y)/n), sum), c(n, ncol(y)/ n), byrow = TRUE)` – David Arenburg Jul 28 '15 at 14:50
  • @DavidArenburg ah, you just edited the comment. Yeah, both these approaches work, though I don't see an easy way to make yours handle the case where n does not evenly divide the number of columns. – josliber Jul 28 '15 at 14:51
  • Well thank you for the quick response @josilber worked exactly how I wanted it to. – Adam Warner Jul 28 '15 at 14:55
2

Transform the matrix to an array and use colSums (as suggested by @nongkrong):

y <- matrix(1:27, nrow = 3)
n <- 3

a <- y
dim(a) <- c(nrow(a), ncol(a)/n, n)
b <- aperm(a, c(2,1,3))
colSums(b)
#     [,1] [,2] [,3]
#[1,]   12   39   66
#[2,]   15   42   69
#[3,]   18   45   72

Of course this assumes that ncol(y) is divisible by n.

PS: You can of course avoid creating so many intermediate objects. They are there for didactic purposes.

Roland
  • 127,288
  • 10
  • 191
  • 288
1

I would do something similar to the OP -- apply rowSums on subsets of the matrix:

n  = 3
ng = ncol(y)/n
sapply( 1:ng, function(jg) rowSums(y[, (jg-1)*n + 1:n ]))

#      [,1] [,2] [,3]
# [1,]   12   39   66
# [2,]   15   42   69
# [3,]   18   45   72
Frank
  • 66,179
  • 8
  • 96
  • 180