Search code examples
rmatrixreplacediagonal

How to replace values in a matrix below the diagonal from bottom left to top right?


Given is a matrix (no assumptions are made about its dimensions) which contains zeros below the diagonal that runs from the bottom left to the upper right corner:

m <- matrix(data = c(2, 1, 8, 9, 1,
                     5, 0, 4, 3, 6,
                     7, 1, 2, 5, 0,
                     3, 1, 0, 0, 0,
                     2, 8, 0, 0, 0,
                     9, 0, 0, 0, 0),
        nrow = 6,
        ncol = 5,
        byrow = TRUE)

The question is how to replace all these zeros below the diagonal with NA? The result should be the following:

       [,1] [,2] [,3] [,4] [,5]
 [1,]    2    1    8    9    1
 [2,]    5    0    4    3    6
 [3,]    7    1    2    5   NA
 [4,]    3    1    0   NA   NA
 [5,]    2    8   NA   NA   NA
 [6,]    9   NA   NA   NA   NA

The matrix may contain zeros elsewhere (on or above the diagonal). These zeros should not be replaced.


Solution

  • Use the base R functions row and col:

    m[row(m) + col(m) > nrow(m) + 1] <- NA
    

    Which gives the desired output:

    > m
          [,1] [,2] [,3] [,4] [,5]
     [1,]    2    1    8    9    1
     [2,]    5    2    4    3    6
     [3,]    7    1    2    5   NA
     [4,]    3    1    3   NA   NA
     [5,]    2    8   NA   NA   NA
     [6,]    9   NA   NA   NA   NA
    

    The trick is to add the row and column number of each cell. All cells that have a number greater than the number of rows plus 1 then correspond to the cells below the diagonal running from the bottom left to the upper right corner.