# Sort matrix by columns and rows without changing them

I would like to sort a matrix in descending order first by the total of each column, then by the total of each row, but without changing their content. For example, if I had:

TableForm[{{0, 0, 1, 1}, {0, 0, 0, 1}, {1, 0, 1, 1}, {1, 1, 1, 1}},
TableHeadings -> {Range[1, 4], Range[1, 4]}]


I want to sort first the columns:

TableForm[{{1, 1, 0, 0}, {1, 0, 0, 0}, {1, 1, 1, 0}, {1, 1, 1, 1}},
TableHeadings -> {Range[1, 4], {"4", "3", "1", "2"}}]


Then the rows:

TableForm[{{1, 1, 1, 1}, {1, 1, 1, 0}, {1, 1, 0, 0}, {1, 0, 0, 0}},
TableHeadings -> {{"4", "3", "1", "2"}, {"4", "3", "1", "2"}}]


The goal is to get as many 1's as possible to the upper-left corner. I added TableHeadings to this mockup of the desired result simply to show the content of the columns/rows remains the same. If there is a better way other than using the Total for each column/row that is fine too. Any help is much appreciated!

Ordering and Part are applicable to this kind of problem. Reverse is needed below as you want to place larger elements to the upper left rather than lower right.

tab = {{0, 0, 1, 1}, {0, 0, 0, 1}, {1, 0, 1, 1}, {1, 1, 1, 1}};

tab = tab[[All, Reverse @ Ordering[tab ~Total~ {1}]]];

tab[[Reverse @ Ordering[tab ~Total~ {2}]]] // TableForm


(This may not be the most efficient algorithm to achieve your goal.)

I believe this can also be done with one application of Part by computing the Ordering for each level beforehand:

newSort[x_?ArrayQ] :=
x[[##]] & @@ (Reverse@Ordering[x ~Total~ {#}] & /@ {2, 1})

newSort[tab]


This could be easily extended to greater dimensions by replacing {2, 1} with Range[ArrayDepth@x, 1, -1].

• I knew about Part, but Ordering was new for me. Thanks @Mr.Wizard! Commented Dec 4, 2012 at 12:45
• @Pancholp You're welcome. Please see the update I just made. Commented Dec 4, 2012 at 13:05

Using Sort :

Sort[Transpose[Sort[Transpose[tab], Total[#1] > Total[#2] &]], Total[#1] > Total[#2] &]

• Thanks @b.gatessucks! This one works well too. Commented Dec 4, 2012 at 12:44

Since V 12.0 there is ReverseSortBy

list = {{0, 0, 1, 1}, {0, 0, 0, 1}, {1, 0, 1, 1}, {1, 1, 1, 1}};

ReverseSort /@ ReverseSortBy[Total] @ list // MatrixForm


Using ReverseSort:

ReverseSort[ReverseSort /@ Transpose[tab]]

(*{{1, 1, 1, 1}, {1, 1, 1, 0}, {1, 1, 0, 0}, {1, 0, 0, 0}}*)