I am attempting to create a cumulative matrix from another matrix. I was playing around with loops and lappy. The following seems to work, but it's very slow. The actual matrix is much larger. I am wondering if there is a more efficient way to create the cumulatrive matrix. Thanks in advance.
# example original matrix:
mat1<-cbind(1:5,1:5,1:5)
# new matrix with the cumulative sum of all previous columns in mat1.
mat2<-mat1
for(i in 2:ncol(mat1)){
mat2[,i]=apply(mat1[,1:i],1,sum)
}
FJCC
August 22, 2022, 4:52pm
2
Maybe using cumsum() will be faster.
mat1<-cbind(1:5,1:5,1:5)
# new matrix with the cumulative sum of all previous columns in mat1.
mat2<-mat1
for(i in 2:ncol(mat1)){
mat2[,i]=apply(mat1[,1:i],1,sum)
}
mat2
#> [,1] [,2] [,3]
#> [1,] 1 2 3
#> [2,] 2 4 6
#> [3,] 3 6 9
#> [4,] 4 8 12
#> [5,] 5 10 15
mat3 <- t(apply(mat1,1,cumsum))
mat3
#> [,1] [,2] [,3]
#> [1,] 1 2 3
#> [2,] 2 4 6
#> [3,] 3 6 9
#> [4,] 4 8 12
#> [5,] 5 10 15
Created on 2022-08-22 by the reprex package (v2.0.1)
This solution from StackOverflow (r - Calculating cumulative sum for each row - Stack Overflow ) seems to be a bit faster:
# define matrix
mat1 <- matrix(c(rep(1:5,3)), ncol = 3)
# define rowCumSum function
colCumSums2 <- function(x) {
matrix(cumsum(rbind(x,-colSums(x))), ncol=ncol(x))[1:nrow(x),]
}
rowCumSums2 <- function(x) {
t(colCumSums2(t(x)))
}
# for the for-loop
mat <- matrix(ncol = 3, nrow = 5)
# comparison
rbenchmark::benchmark(
forloop = for(i in 2:ncol(mat1)){mat[,1] <- apply(mat1[,1:i],1,sum)},
cumsum = t(apply(mat1, 1, cumsum)),
rowCumSums = rowCumSums2(mat1),
replications = 1000
)
#> test replications elapsed relative user.self sys.self user.child sys.child
#> 2 cumsum 1000 0.17 2.833 0.11 0.05 NA NA
#> 1 forloop 1000 10.97 182.833 8.97 0.33 NA NA
#> 3 rowCumSums 1000 0.06 1.000 0.06 0.00 NA NA
Created on 2022-08-22 with reprex v2.0.2
Much faster and simpler. Thank-you!
system
Closed
September 12, 2022, 6:58pm
5
This topic was automatically closed 21 days after the last reply. New replies are no longer allowed. If you have a query related to it or one of the replies, start a new topic and refer back with a link.