yliueagle
yliueagle

Reputation: 1201

Retrieve upper triangular elements of a matrix and order them by off-diagonal order

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

Answers (1)

Julius Vainora
Julius Vainora

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

Related Questions