matrix r

# Sorting a matrix whilst preserving the diagonal in R?

I was wondering if there was a generic way to sort a symmetrical matrix in `R`, whilst preserving the diagonal values.

For example, if I have a matrix like this:

``````# Create Matrix -----------------------------------------------------------
offdiag <- c(rep(1:6))
m <- matrix(NA, ncol = 4, nrow = 4,dimnames = list(c("A","B","C","D"), c("A","B","C","D")))
m[lower.tri(m)] <- offdiag
m[upper.tri(m)] <- t(m)[upper.tri(t(m))]
diag(m) <- 0
m
``````

which produces this:

``````  A B C D
A 0 1 2 3
B 1 0 4 5
C 2 4 0 6
D 3 5 6 0
``````

In the above example the values C and D share the largest value. So what I am trying to achieve is to reorder the matrix so the largest value is in the top left of the upper triangle (whilst not altering the diagonal 0's).

So if I were to explicitly rearrange the matrix, by hand, the final result would be:

``````# Create sorted matrix by hand --------------------------------------------
A <- c(2,3,0,1)
B <- c(4,5,1,0)
C <- c(0,6,2,4)
D <- c(6,0,3,5)

matr <- cbind(C,D,A,B)
rownames(matr) <- c("C","D","A","B")
matr
``````

which would produce:

``````  C D A B
C 0 6 2 4
D 6 0 3 5
A 2 3 0 1
B 4 5 1 0
``````

What I'm wondering is, is there a way to generically sort the matrix like in my example for a (n X n) matrix?

Questioner
Electrino
Viewed
52 ThomasIsCoding 2020-01-31 23:36

Maybe you can try the code below

``````q <- which(colSums(m == max(m))>0,arr.ind = T)
o <- c(q, seq(ncol(m))[-q])
mout <- m[o,o]
``````

such that

``````> mout
C D A B
C 0 6 2 4
D 6 0 3 5
A 2 3 0 1
B 4 5 1 0
``````