2

The off-diagonal elements of the mat_rix below are all 0s.

To extract the off-diagonal elements, I use a solution that I found on SO: odiag <- function(x) x[(n <- nrow(x))^2-(1:n)*(n-1)]

But when I use odiag(mat_rix), the output contains non-0 elements. I wonder what's the problem and how to fix it?

x="
 0.4850377 0.000000 0.00000000 0.00000000 0.0000000 0.000000 0.0000000 0.0000000 0.0000000 0.0000000 0.0000000
 0.0000000 0.510766 0.00000000 0.00000000 0.0000000 0.000000 0.0000000 0.0000000 0.0000000 0.0000000 0.0000000
 0.0000000 0.000000 0.05767389 0.00000000 0.0000000 0.000000 0.0000000 0.0000000 0.0000000 0.0000000 0.0000000
 0.0000000 0.000000 0.00000000 0.07539841 0.0000000 0.000000 0.0000000 0.0000000 0.0000000 0.0000000 0.0000000
 0.0000000 0.000000 0.00000000 0.00000000 0.3134951 0.000000 0.0000000 0.0000000 0.0000000 0.0000000 0.0000000
 0.0000000 0.000000 0.00000000 0.00000000 0.0000000 0.679101 0.0000000 0.0000000 0.0000000 0.0000000 0.0000000
 0.0000000 0.000000 0.00000000 0.00000000 0.0000000 0.000000 0.5067036 0.0000000 0.0000000 0.0000000 0.0000000
 0.0000000 0.000000 0.00000000 0.00000000 0.0000000 0.000000 0.0000000 0.1829717 0.0000000 0.0000000 0.0000000
 0.0000000 0.000000 0.00000000 0.00000000 0.0000000 0.000000 0.0000000 0.0000000 0.3722585 0.0000000 0.0000000
 0.0000000 0.000000 0.00000000 0.00000000 0.0000000 0.000000 0.0000000 0.0000000 0.0000000 0.3907239 0.0000000
 0.0000000 0.000000 0.00000000 0.00000000 0.0000000 0.000000 0.0000000 0.0000000 0.0000000 0.0000000 0.0287955"

mat_rix <- as.matrix(read.table(text=x))

odiag(mat_rix)

[1] 0.000000 0.000000 0.000000 0.000000 0.000000 0.679101 0.000000 0.000000 0.000000 0.000000 0.000000
Simon Harmel
  • 927
  • 2
  • 9
  • 1
    It may be more informative to use an example of, for example, `matrix(1:16, 4, 4)` and then declare which values you would like extracted. It a bit hard to see if the correct values, or the order in which they are extracted is correct if they are all zero – user20650 Dec 26 '21 at 18:06

1 Answers1

3

If we need the off-diagonal, create a function where the row index is not equal to column index

odiag <- function(x) x[col(x) != row(x)]
odiag(mat_rix)

If we need the values that are one up/one down from the diagonal

odiag2 <- function(x, offdiag = "up") {
    ind <- if(offdiag == "up") -1 else 1
    x[row(x) - col(x) == ind]
}
odiag2(mat_rix, "up")
[1] 0 0 0 0 0 0 0 0 0 0
akrun
  • 874,273
  • 37
  • 540
  • 662
  • 1
    Thinking you and OP `might` have different 'off diagonal' expectations as your off is all off, agnostic as to upper or lower off, hence length 110, in this case, where it appears OP is looking for 'one' off, again agnostic to upper lower, but length 10. – Chris Dec 26 '21 at 17:52
  • @Chris I posted this as comment and the OP told me to post as a solution. So, I would assume that this is what OP meant – akrun Dec 26 '21 at 17:53
  • I was looking at the length of his prior output, which wasn't complained of, except the indexing that brought in the non-zero, But his check will clarify. – Chris Dec 26 '21 at 17:57
  • @Chris I noticed that too. That is the reason I commented and then he replied. I would have kept my comments below his post – akrun Dec 26 '21 at 17:58
  • 1
    And choosing one's diagonal from those available [extracting off diagonal](https://stackoverflow.com/questions/27935555/get-all-diagonal-vectors-from-matrix) using `split`. – Chris Dec 26 '21 at 18:52
  • A question of interest [HERE](https://stackoverflow.com/q/70490158/16762740). – Simon Harmel Dec 26 '21 at 22:06
  • @SimonHarmel it seems to be deleted though – akrun Dec 27 '21 at 17:41