Home > Back-end >  How to calculate matrix cumsum by condition in R?
How to calculate matrix cumsum by condition in R?

Time:07-15

Lets say I have a 2x2 - matrix like:

enter image description here

and try to find the cumsum till position [0,1], which would be 1 3 = 4 or [1,0] which equals to 1 2 = 3

So only the values, which matched the criteria, will be summed together.. Is there a function/method to this?

CodePudding user response:

You are looking for the sum of a leading block of a matrix? This is most straightforward if you work with numeric index. In case of character index (i.e., row names and column names), we can match for numeric index before doing sum.

mat <- matrix(1:4, 2, 2, dimnames = list(0:1, 0:1))

rn <- "0"; cn <- "1"
sum(mat[1:match(rn, rownames(mat)), 1:match(cn, colnames(mat))])
#[1] 4

rn <- "1"; cn <- "0"
sum(mat[1:match(rn, rownames(mat)), 1:match(cn, colnames(mat))])
#[1] 3

Could you maybe explain to me why this code works?

In general, you can extract a block of a matrix mat, between rows i1 ~ i2 and columns j1 ~ j2 using mat[i1:i2, j1:j2]. A leading block means that the starting row and column are i1 = 1 and j1 = 1. In your case, the terminating row and column are to be determined by names, so I do match to first find the right i2 and j2.

I could sort of see your motivation. This is like selecting a region in an Excel sheet. :)

CodePudding user response:

Another possibility:

m <- matrix(1:4,nrow=2)
m
#>      [,1] [,2]
#> [1,]    1    3
#> [2,]    2    4
pos <- c(1,0)
pos <- pos   1
sum(m[1:pos[1],1:pos[2]])
#> [1] 3

pos <- c(0,1)
pos <- pos   1
sum(m[1:pos[1],1:pos[2]])
#> [1] 4

CodePudding user response:

cumsum of the first column of the matrix AsIs then that of the transpose.

lapply(list(I, t), \(f) {r <- unname(cumsum(f(m)[, 1])); r[length(r)]})
# [[1]]
# [1] 3
# 
# [[2]]
# [1] 4

Data:

m <- matrix(c(1, 2, 3, 4), 2, 2)
  • Related