Reputation: 1201
I have a matrix (dimension can be large) and want to retrieve all upper triangular elements then order them by off-diagonal order. For example, given A = matrix(1:25, 5, 5)
, the output res
is
res = c( c(6,12,18,24), c(11,17,23), c(16,22), c(21) )
## i.e, res = c(offdiag_vect_1, offdiag_vect_2, offdiag_vect_3, offdiag_vect_4)
I know the upper triangular elements can be retrieved through A[upper.tri(A, diag=FALSE)]
, but not sure how to re-order them in a c(offdiag_vect_1, offdiag_vect_2, ..., offdiag_vect_(n-1))
manner in an efficient way.
Upvotes: 2
Views: 248
Reputation: 48241
Borrowing from my other answer, you may use
split(A, col(A) - row(A))
to get a list of all diagonals. Then adding tail
allows to get only the upper ones, and unlist
gives a vector:
unlist(tail(split(A, col(A) - row(A)), ncol(A) - 1))
# 11 12 13 14 21 22 23 31 32 4
# 6 12 18 24 11 17 23 16 22 21
Adding unname
yields gets rid off the names:
unname(unlist(tail(split(A, col(A) - row(A)), ncol(A) - 1)))
# [1] 6 12 18 24 11 17 23 16 22 21
For a large matrix it should help not to compute the irrelevant diagonals. Then
unname(unlist(split(A[upper.tri(A)], (col(A) - row(A))[upper.tri(A)])))
# [1] 6 12 18 24 11 17 23 16 22 21
Upvotes: 1