Search code examples
rmatrixmatrix-indexing

How to insert values from a vector diagonally into a matrix in R?


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

Solution

  • 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