tzu
tzu

Reputation: 183

How to reorder columns by the order of rows in the same matrix?

Suppose I have a 10*10 matrix---A, in which the names and the order of columns are identical to rows (a, b, c,.., j). Due to calculating the characteristics of the matrix, I have to reorder the rows and columns by their attribute, say "attr". Assuming that the attr of a, c, e equals to 1, attr of b, f, i, j equals to 2, and attr of d, g, h equals to 3. I figure out a way to reorder the rows as:

Anew <- rbind(subset(A, attr==1), subset(A, attr==2), subset(A, attr==3))

Now I have a new matrix Anew, in which the order of rows is a, c, e, b, f, i, j, d, g, h, and the order of columns remains the same as a,...,j. My question is that how I can reorder the column in Anew by the order of rows of Anew? I understand that I can use code such as

cbind(Anew[,a], Anew[,c],...,Anew[,h])

but is there a more efficient way to do this? If the matrix was 100*100, the code above is very insufficient. Thank you.

Upvotes: 1

Views: 455

Answers (1)

akrun
akrun

Reputation: 887691

We can order the attr and use that as row index

Anew <- A[order(as.numeric(attr(A, 'row.names'))),]
Anew
#          a          b           c           d           e          f          g           h            i          j
#a -0.545880758 -1.3169081 -0.07430856 -0.03373792  0.06735770  0.5266526  1.4520752  0.14379993 -0.571243248 -0.2327672
#c  0.419623149 -0.7622144 -1.70964518  0.61285136 -0.34365937  0.7696819 -0.4403340 -0.02557419 -1.673385810 -0.8133227
#e  0.847460017  0.3322444 -0.64859151  0.65738044 -0.25574457 -0.1961822  0.5713866 -0.07596102  0.361212489 -0.2148936
#b  0.536585304  0.5982691 -0.60515695 -0.58542756  0.01710596 -1.0736261  0.4082015 -0.88610999  0.422621775 -1.4203631
#f  0.266021979 -0.4690607 -0.09411013 -1.07418134 -0.46120796  0.2047497 -1.2799872 -1.35466363  1.056864213  0.1389452
#i -0.848370044  0.6099945 -0.11629639  0.16922669  0.33519430  1.0494212  1.3496121 -0.12316046  0.007165349  1.0451687
#j  0.002311942  0.5163357 -0.94382724 -1.82219032 -0.23186459  0.5609812 -1.5676166  0.00104102  0.101974336  1.2101739
#d -0.583627199 -1.4290903 -0.26869311  1.51712249 -0.66789220  1.7709054  1.3185662 -0.32773539 -1.136025931  0.4610693
#g  0.444585270 -0.3349868 -0.08554095 -4.46956441  1.47164158 -0.5965981 -1.2388796 -0.96080882 -1.992920453  0.8442304
#h -0.466495124  1.5362522  0.11953107  0.36904502 -0.09196032  1.1782477 -0.9225911  0.22495434  0.764385054 -1.3084503

If we want to do this for row and column

 Anew1 <- A[order(as.numeric(attr(A, 'row.names'))), order(as.numeric(attr(A, 'col.names')))]

data

set.seed(24)
A <- matrix(rnorm(10*10), ncol=10, dimnames=list(letters[1:10], letters[1:10]))
attr(A, 'row.names') <-  as.character(c(1, 2, 1,3, 1, 2, 3, 3, 2, 2))
attr(A, 'col.names') <-  as.character(c(1, 2, 1,3, 1, 2, 3, 3, 2, 2))

Upvotes: 3

Related Questions