Create new matrix in R by summing rows of another matrix

Viewed 57

So I have the following matrix (let's call it output):

> output

     [,1] [,2] [,3] [,4] [,5] [,6] 
[1,]   1    1    1    0    0    1
[2,]   1    1    1    0    0    1
[3,]   1    1    1    0    0    1
[4,]   0    0    0    0    0    0
[5,]   1    0    1    1    0    0 
[6,]   1    0    1    1    0    0

What I want to do is to create a new matrix (output2) by adding rows in groups of two. For example the first row of the new matrix would be:

output2[1,] <- output[1,] + output[2,]

The second row of the new matrix output2 would consist of the sum of the third and fourth row of the old output matrix:

output2[2,] <- output[3,] + output[4,]

And so forth. I was wondering what is the best way to code this, considering I will need to do the same to bigger matrices. I was considering creating dummy variables with the seq() function and maybe a for loop.

Is there a simpler way?

Edit:

dput(output)

structure(c(1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0), .Dim = c(10L, 19L))

3 Answers

If m is your matrix, try this:

m[seq(1,by=2,to=nrow(m)),]+m[seq(2,by=2,to=nrow(m)),]

These both:

  • handle both even and odd numbers of rows
  • generalize to k rows by replacing 2 with k
  • are short -- one line of code or could easily be made one line
  • (1) uses only base functions, i.e. no packages and (2) can be readily generalized to functions other than sum.

1) rowsum Use rowsum with a second argument of c(1, 1, 2, 2, ..., 5, 5) which is readily created using gl:

nr <- nrow(output)
rowsum(output, gl(nr, 2, nr))

2) rollapply Another possibility is to use rollapply from zoo. If we knew that the number of rows was even we could optionally omit the align and partial arguments.

library(zoo)
rollapply(output, 2, by = 2, sum, align = "left", partial = TRUE)

Another option is to use vector recycling:

matrix(output[c(TRUE, FALSE)] + output[c(FALSE, TRUE)], ncol = ncol(output))
Related