I need to insert a vector diagonally into a matrix on an arbitrary place. I know how to insert a vector vertically or horizontally but I can't do it diagonally.
I have:
A <- matrix(nrow=6,ncol=6)
b <- c(1:4)
The desired result (if I want to insert the vector in the position A[3,2]
), would be:
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] NA NA NA NA NA NA
[2,] NA NA NA NA NA NA
[3,] NA 1 NA NA NA NA
[4,] NA NA 2 NA NA NA
[5,] NA NA NA 3 NA NA
[6,] NA NA NA NA 4 NA
Also, I want to be able to insert the vector to get this matrix (starting from A[4,1]
):
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] NA NA NA 4 NA NA
[2,] NA NA 3 NA NA NA
[3,] NA 2 NA NA NA NA
[4,] 1 NA NA NA NA NA
[5,] NA NA NA NA NA NA
[6,] NA NA NA NA NA NA
To convert a vector into a diagonal matrix in R, we can use diag function along with matrix function and use ncol argument where we can put the number of columns equal to the number of values in the vector.
D = diag( v ) returns a square diagonal matrix with the elements of vector v on the main diagonal. D = diag( v , k ) places the elements of vector v on the k th diagonal. k=0 represents the main diagonal, k>0 is above the main diagonal, and k<0 is below the main diagonal.
diag() function in R Language is used to construct a diagonal matrix. Syntax: diag(x, nrow, ncol) Parameters: x: value present as the diagonal elements. nrow, ncol: number of rows and columns in which elements are represented.
Here's one possibility (you could probably wrap it up into a function)
indx <- 0:(length(b) - 1) # Create an index
Frow <- 3 ; Fcol <- 2 #initiate rows/cols
A[cbind(Frow + indx, Fcol + indx)] <- b
A
# [,1] [,2] [,3] [,4] [,5] [,6]
# [1,] NA NA NA NA NA NA
# [2,] NA NA NA NA NA NA
# [3,] NA 1 NA NA NA NA
# [4,] NA NA 2 NA NA NA
# [5,] NA NA NA 3 NA NA
# [6,] NA NA NA NA 4 NA
For your second output (Assuming A
matrix is all NA
s again)
Frow <- 4 ; Fcol <- 1
A[cbind(Frow - indx, Fcol + indx)] <- b
A
# [,1] [,2] [,3] [,4] [,5] [,6]
# [1,] NA NA NA 4 NA NA
# [2,] NA NA 3 NA NA NA
# [3,] NA 2 NA NA NA NA
# [4,] 1 NA NA NA NA NA
# [5,] NA NA NA NA NA NA
# [6,] NA NA NA NA NA NA
You can use this function:
insert.diag <- function(A,b,start=c(1,1),dir=c(1,1)) {
sq <- seq_along(b)-1
indices <- sapply(1:2,function(i) start[i] + dir[i]*sq)
stopifnot(all(indices>0))
stopifnot(all(indices[,1]<=nrow(A)))
stopifnot(all(indices[,2]<=ncol(A)))
A[indices] <- b
A
}
Some examples of use:
A <- matrix(nrow=6,ncol=6)
b <- c(1:4)
> insert.diag(A,b,c(1,6),c(1,-1))
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] NA NA NA NA NA 1
[2,] NA NA NA NA 2 NA
[3,] NA NA NA 3 NA NA
[4,] NA NA 4 NA NA NA
[5,] NA NA NA NA NA NA
[6,] NA NA NA NA NA NA
> insert.diag(A,b,c(6,6),c(-1,-1))
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] NA NA NA NA NA NA
[2,] NA NA NA NA NA NA
[3,] NA NA 4 NA NA NA
[4,] NA NA NA 3 NA NA
[5,] NA NA NA NA 2 NA
[6,] NA NA NA NA NA 1
> insert.diag(A,b,c(1,1),c(1,1))
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 1 NA NA NA NA NA
[2,] NA 2 NA NA NA NA
[3,] NA NA 3 NA NA NA
[4,] NA NA NA 4 NA NA
[5,] NA NA NA NA NA NA
[6,] NA NA NA NA NA NA
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