0
votes

I am trying to solve a little problem with a matrix in R. I have the next matrix in R (alfa):

alfa <- matrix(1:9,nrow=3)

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

The opposite diagonal of alfa is filled of zeros. I would like to get in a new matrix all elements over this opposite diagonal (maybe the upper triangle over this diagonal). I wish to get a new matrix like this:

     [,1] [,2] [,3]
[1,]    1    4    0
[2,]    2    0    0
[3,]    0    0    0

Or like this matrix with NA:

     [,1] [,2] [,3]
[1,]    1    4    0
[2,]    2    0   NA
[3,]    0   NA   NA

Where the elements located down the opposite diagonal of alfa are zero or NA, as you can see. I have tried with code using row(alfa) and col(alfa) but I can't get the expected matrix, for example:

(row(alfa)+col(alfa)-1)%%ncol(alfa)!=0

And I got this result where both upper and down elements over opposite diagonal are TRUE:

      [,1]  [,2]  [,3]
[1,]  TRUE  TRUE FALSE
[2,]  TRUE FALSE  TRUE
[3,] FALSE  TRUE  TRUE

But I only want the upper elements, and the rest elements should be filled with zero or NA.

Many thanks for your help.

2
While the reproducible data is appreciated, wouldn't it have been simpler to provide a small matrix, like matrix(1:9,nrow=3)? The function should be the same, no?thelatemail
Does this work? m[(row(m) + col(m) - ncol(m) > 0] <- 0 where m is your matrix.user20650
Yes @thelatemail sorry I will take your recommendation next time!!!Duck
oops, missing ). Should be alfa[(row(alfa) + col(alfa) - ncol(alfa)) > 0] <- 0 (changing m for alfa)user20650

2 Answers

3
votes

lower.tri almost does what you want, but you need to reverse the rows.

alfa[apply(lower.tri(alfa), 1, rev)] <- NA

Here, the matrix of the lower anti-diagonal is built, and used to select into alfa (vector indexing) for replacement.

lower.tri has a diag argument, which will also select the diagonal if set to TRUE.

2
votes
f <- function(mat, diag = 0, offdiag = NA){
  rev_vec <- seq(ncol(mat), 1)
  j <- mat[,rev_vec]
  j[lower.tri(j)] <- offdiag
  diag(j) <- diag
  j[,rev_vec]
}

You can specify if you want the off-diagonals to be NA or 0 by changing the offdiag parameter.