# How to aggregate rows/columns of a matrix by keeping row/column headings

The following code works for matrices without row/column headings and I like to carry out the aggregation of the selected rows and columns by keeping row/column headings.

ClearAll[mat2, aggregationSUM, aggmat];

aggregationSUM =(*IO matrix aggregation with headings*)
Fold[Module[{m = Transpose@#, x = #2},
ReplacePart[m,
Join[#[[1]] -> Plus @@ m[[#]] & /@
x, {Alternatives @@ Flatten[x[[All, 2 ;;]]] ->
Sequence[]}]]] &, #, {##2}] &;    (developed by @kglr)

mat2 = {
{0, c1s1, c1s2, c1s3, c2s1, c2s2, c2s3, c3s1, c3s2, c3s3,
c1d1, c1d2, c2d1, c2d2, c2d3, c3d1, c3d2}, {c1s1, 1, 3, 0, 2, 2,
2, 3, 2, 0, 3, 1, 2, 0, 3, 3, 0}, {c1s2, 2, 2, 0, 0, 3, 0, 0, 0,
0, 0, 0, 3, 0, 1, 2, 0}, {c1s3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0}, {c2s1, 2, 1, 0, 0, 2, 0, 2, 3, 0, 2, 3, 1, 0, 2,
2, 1}, {c2s2, 1, 3, 0, 0, 2, 1, 3, 0, 0, 3, 3, 2, 0, 1, 2,
3}, {c2s3, 3, 3, 0, 0, 2, 2, 3, 1, 0, 2, 2, 2, 0, 0, 2, 3}, {c3s1,
1, 2, 0, 0, 2, 0, 3, 0, 0, 1, 0, 1, 0, 2, 3, 1}, {c3s2, 2, 0, 0,
2, 2, 0, 3, 0, 0, 3, 1, 1, 0, 1, 3, 3}, {c3s3, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {c1t, 3, 1, 0, 0, 0, 3, 1, 0, 0, 0,
1, 2, 0, 2, 0, 0}, {c2t, 2, 1, 0, 0, 3, 3, 3, 0, 0, 2, 1, 0, 0,
3, 1, 2}, {c3t, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0}, {va, 3, 2, 0, 0, 1, 3, 0, 2, 0, 1, 3, 2, 0, 3, 3, 1}};

aggmat = aggregationSUM[mat2,
{{2, 3}, {6, 7, 8}},   (*rows*)
{{2, 3}, {6, 7, 8}}    (*columns*)]

labRow={r1, r2};   (*new labels for the aggregated rows*)
labCol={c1, c2};   (*new labels for the aggregated columns*)


It will convenient if these labels are created automatically by linking them to aggregationSUM[].

## 1 Answer

ClearAll[aggregationSumWithHeaders]
aggregationSumWithHeaders = Fold[Module[{m = Transpose @ #, x = 1 + #2},
ReplacePart[m, Join[#[[1, 1]] ->
ReplacePart[Total[m[[#[[1]]]]], 1 -> #[[2]] - 1] & /@ x,
{Alternatives @@ Flatten[x[[All, 1, 2 ;;]]] -> Sequence[]}]]] &, #, {##2}] &;

labRow = Highlighted /@ {r1, r2};
labCol = Highlighted /@ {c1, c2};

aggregationSumWithHeaders[mat2,
Thread[{{{2, 3}, {6, 7, 8}}, Highlighted /@ labCol}],
Thread[{{{2, 3}, {6, 7, 8}}, Highlighted /@ labRow}] ] // MatrixForm


• When I run aggregationSumWithHeaders[ mat2, {{2, 3}, {6, 7, 8}}, {{2, 3}, {6, 7, 8}} ], I receive the error Part specification {3,4}[[1,1]] is longer than depth of object. Is there anything I do wrong here? Feb 5, 2021 at 1:40
• @Tugrul, to avoid hard-coded new labels we need to provide Indices as well as labels for each list of rows/columns to be combined. So we need to use aggregationSumWithHeaders[mat2, Thread[{{{2, 3}, {6, 7, 8}}, labCol}], Thread[{{{2, 3}, {6, 7, 8}}, labRow}]] or aggregationSumWithHeaders[mat2, {{{2, 3}, c1}, {{6, 7, 8}, c2}}, {{{2, 3}, r1}, {{6, 7, 8}, r2}}]
– kglr
Feb 5, 2021 at 1:54