Given a vector I would like to create a square matrix where elements of vector are on diagonal and there is row-wise cumsum of elements.
Example vector:
vec <- c(1, 2, 3, 4)
Required output:
[,1] [,2] [,3] [,4]
[1,] 1 3 6 10
[2,] 0 2 5 9
[3,] 0 0 3 7
[4,] 0 0 0 4
Now, I am using double for loop function:
diagSum <- function(vec) {
mat <- diag(vec)
for (i in seq(nrow(mat))) {
for (j in seq(i, ncol(mat))) {
if (j > i) {
mat[i, j] <- mat[i, j - 1] + mat[j, j]
}
}
}
mat
}
What would be R-way (avoiding for loops) of doing this?
m <- matrix(vec, nrow = length(vec), ncol = length(vec), byrow =TRUE)
m[lower.tri(m)] <- 0
t(apply(m, 1, cumsum))
# [,1] [,2] [,3] [,4]
#[1,] 1 3 6 10
#[2,] 0 2 5 9
#[3,] 0 0 3 7
#[4,] 0 0 0 4
One way to do it:
x <- c(1, 2, 3, 4)
rbind(cumsum(x), t(sapply(1:3, function(y) c(rep(0, y), cumsum(x[-(1:y)])) )))
# [,1] [,2] [,3] [,4]
# [1,] 1 3 6 10
# [2,] 0 2 5 9
# [3,] 0 0 3 7
# [4,] 0 0 0 4
Like this:
> x=c(1, 2, 3, 4)
> do.call(rbind, lapply(1:length(x)-1, function(u) {x[0:u]=0;cumsum(x)}))
# [,1] [,2] [,3] [,4]
#[1,] 1 3 6 10
#[2,] 0 2 5 9
#[3,] 0 0 3 7
#[4,] 0 0 0 4
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With