1

I would like to transform a matrix of 0s and 1s into a corresponding matrix that gives the cumulative row sum for non-zero entries. Example input and output is given below:

set.seed(404)
input  <- matrix(rbinom(10 * 5, 1, 0.5), ncol = 5, nrow = 5)
output <- data.frame(a = c(1, 1, 1, 1, 0),
                     b = c(0, 0, 0, 0, 0),
                     c = c(2, 2, 0, 2, 1),
                     d = c(3, 0, 0, 3, 2),
                     e = c(0, 3, 0, 0, 0))

input
#     [,1] [,2] [,3] [,4] [,5]
#[1,]    1    0    1    1    0
#[2,]    1    0    1    0    1
#[3,]    1    0    0    0    0
#[4,]    1    0    1    1    0
#[5,]    0    0    1    1    0
output
#  a b c d e
#1 1 0 2 3 0
#2 1 0 2 0 3
#3 1 0 0 0 0
#4 1 0 2 3 0
#5 0 0 1 2 0
Dason
  • 60,663
  • 9
  • 131
  • 148
jonnie
  • 745
  • 1
  • 13
  • 22
  • 1
    It looks like you got a good answer here, but please note that the best received questions on this site typically include your own attempt at solving the problem and a description of difficulties you've run into. – josliber Aug 27 '15 at 15:21
  • you are right. i tried ranking and then messing around with lists, but i had no idea how to tackle the problem and keep the matrix structure – jonnie Aug 27 '15 at 15:40

1 Answers1

4

We can use apply with MARGIN=1 to get the cumsum of each row of 'input', transpose (t) and multiply with 'input' so that the 1 values gets replaced by the cumsum output and '0' remain the same.

input*t(apply(input, 1, cumsum))
#   [,1] [,2] [,3] [,4] [,5]
#[1,]    1    0    2    3    0
#[2,]    1    0    2    0    3
#[3,]    1    0    0    0    0
#[4,]    1    0    2    3    0
#[5,]    0    0    1    2    0

Or we can use rowCumsums from library(matrixStats) to get the cumsum of each row and multiply as before.

library(matrixStats)
input*rowCumsums(input)
#     [,1] [,2] [,3] [,4] [,5]
#[1,]    1    0    2    3    0
#[2,]    1    0    2    0    3
#[3,]    1    0    0    0    0
#[4,]    1    0    2    3    0
#[5,]    0    0    1    2    0
akrun
  • 874,273
  • 37
  • 540
  • 662
  • amazing. i apologize for moving the goal posts here, but do you know a solution with a matrix of -1, 0, 1's? where the negative values get added up and the positive values begin adding up – jonnie Aug 27 '15 at 15:17
  • 2
    @user1499626 That should be a separate question. – akrun Aug 27 '15 at 15:18
  • 1
    Some benchmarking implies that the second solution is quite a bit faster. – Dason Aug 27 '15 at 16:25