# Rearranging a biclustered matrix

I currently have a $77\times 38$ matrix, and I have used a clustering algorithm to cluster the row data and column data. The rows and columns of my matrix correspond to a list of country codes (not in numerical order). That is, I have a list of numbers:

{10, 28, 34, 44, ...}


where country 10 corresponds to row 1, country 28 to row 2, etc. I have a corresponding list for the columns of my matrix. I have independently clustered the columns and rows into groups of 3. For example, the row clusters look like so:

{{10, 1, 4, 2, ...,37 }, {28, 34, 27, 21, ..., 18}, {38, 20, ..., 12}}


Again, I have another clustering for the columns. I want to rearrange the rows and columns of my matrix such that the clustered rows and columns are next to one another. Using my example row cluster list, I want to rearrange the matrix such that row 1 corresponds to country 10, row 2 to country 1, row 3 to country 4, etc. After this, I wish to do the same with the columns of my matrix. Any help is appreciated.

• Please include a small example matrix that demonstrates the idea... it's hard to follow the logic when you explain it in 3 paragraphs. – rm -rf Nov 6 '12 at 1:08
• With incomplete data and no working code you are literally making your (possibly simple) question sound like an excruciating puzzle Dr. Watson..:( – PlatoManiac Nov 6 '12 at 1:10

Update: I think Part covers all the manipulations you need to do on the rows and columns of your matrix:

mtrx = Array[Subscript[a, ##] &, {4, 3}];
Grid[Thread[{{HoldForm[mtrx], HoldForm[mtrx[[{2, 1, 4, 3}, All]]],
HoldForm[mtrx[[All, {2, 1, 3}]]], HoldForm[mtrx[[{2, 1, 4, 3}, {2, 1, 3}]]],
HoldForm[mtrx[[{1, 2, 1, 2, 1}, {3, 2}]]]},
TableForm /@ {mtrx, mtrx[[{2, 1, 4, 3}, All]],
mtrx[[All, {2, 1, 3}]], mtrx[[{2, 1, 4, 3}, {2, 1, 3}]],
mtrx[[{1, 2, 1, 2, 1}, {3, 2}]]}}],
Spacings -> {1, 1}, Frame -> All]


If data is your data matrix and rowClusterList and columnClusterList are the partitions corresponding to the row and column clusterings, you can re-arrange the rows and columns of your data matrix using:

 data[[Flatten@rowClusterList,Flatten@columnClusterList]]


Original post based on guessing the details of the problem --( keeping for now hoping it may prove relevant and useful based on expected updates by the OP to his post.)

A small example for illustration

(* a short list of countries *)
(* countryList=RandomChoice[CountryData[#, "Name"] & /@ CountryData["Countries"], {10}] *)
countryList = {"Cyprus", "Macau", "Barbados", "Kuwait", "Hungary",
"El Salvador", "Jamaica", "Oman", "Myanmar", "Peru"};
(* example data *)
data = RandomInteger[{5}, {10, 10}];
TableForm[data, TableHeadings -> {countryList, Rotate[#, 90 Degree] & /@ countryList}]


ArrayPlot[data, ColorFunction -> "Rainbow", Mesh -> All,
Frame -> True, FrameTicksStyle -> Opacity[1],
FrameTicks -> {{ticks,  None}, {ticks /. s_String :> Rotate[s, 90 Degree], None}},
ImagePadding -> {{60, 10}, {60, 10}}]


 (* example clustering of the rows and columns:*)
rowClusters = {{2, 3, 5}, {1, 9, 4}, {7, 8, 10, 6}};
columnClusters = {{10, 2, 3, 9}, {1, 6, 8, 5}, {7, 4}};


Reshuffle the data matrix and the row/column indices to match the new row and column orderings:

 newdata = data[[Flatten@rowClusters, Flatten@columnClusters]];
countryList[[Flatten@columnClusters]]}];
Rotate[#, 90 Degree] & /@ countryList[[Flatten@columnClusters]]}]


 ArrayPlot[newdata, ColorFunction -> "Rainbow",
Mesh -> {Join[{0},  Accumulate@(Length /@ rowClusters), {Length[data]}],
Join[{0}, Accumulate@(Length /@ columnClusters), {Length[data]}]},
MeshStyle -> {Directive[GrayLevel[.1], Thickness[.01]],
Directive[GrayLevel[.1], Thickness[.01]]},
Frame -> True,  FrameTicksStyle -> Opacity[1],
FrameTicks -> {{xticks, None}, {yticks /. s_String :> Rotate[s, 90 Degree], None}},
ImagePadding -> {{60, 10}, {60, 10}}]


• I feel one more step is necessary: The cluster lists are list of numeric labels, they are not row or column numbers. So, you have to make an additional translation to arrive at that. – Sjoerd C. de Vries Nov 6 '12 at 13:43
• @Sjoerd, good point. Will post an update with the needed step. – kglr Nov 6 '12 at 19:07