Cascading sort order that restarts count at each subsequent column

I'm trying to sort a table by multiple columns (easy) and obtain a specialized sort order (not-so-easy).
Rather than a sortIndex vector I'm trying to get a sortIndex matrix where each column's count restarts from 1 as a preceding column changes. This is kind of like a set of cascading counters that restart back at 1 as any of the preceding counters tick forward.
Here's some data:
DAT = array2table([
"A" "a" "1"
"A" "a" "2"
"B" "a" "3"
"C" "a" "3"
"C" "b" "5"
"C" "a" "4"
"C" "b" "6"
"C" "b" "7"
], 'Var', ["ColA" "ColB" "ColC"])
And here's a clunky nested loop that achieves what I'm looking for in the specific case of having 3 columns to my data:
Omat = zeros(height(DAT),3);
[~,~,grpA] = unique(DAT.ColA,'stable');
Omat(:,1) = grpA;
for noA = 1:max(grpA)
maskA = grpA==noA;
subIndsA = find(maskA);
[~,~,subGrpB] = unique(DAT.ColB(maskA),'stable');
Omat(subIndsA,2) = subGrpB;
for noB = 1:max(subGrpB)
subMaskB = subGrpB==noB;
[~,~,subSubGrpC] = unique(DAT.ColC(subIndsA(subMaskB)),'stable');
Omat(subIndsA(subMaskB),3) = subSubGrpC;
end
end
And here's the output next to the original data:
Omat =
1 1 1 % "A" "a" "1"
1 1 2 % "A" "a" "2"
2 1 1 % "B" "a" "3"
3 1 1 % "C" "a" "3"
3 2 1 % "C" "b" "5"
3 1 2 % "C" "a" "4"
3 2 2 % "C" "b" "6"
3 2 3 % "C" "b" "7"
Can anyone think of a cleaner implementation that can generalize to N columns?

답변 (1개)

DAT = array2table([
"A" "a" "1"
"A" "a" "2"
"B" "a" "3"
"C" "a" "3"
"C" "b" "5"
"C" "a" "4"
"C" "b" "6"
"C" "b" "7"
], 'Var', ["ColA" "ColB" "ColC"]) ;
for i = 1:3
DAT.(i) = grp2idx(DAT.(i)) ;
end
DAT
DAT = 8×3 table
ColA ColB ColC ____ ____ ____ 1 1 1 1 1 2 2 1 3 3 1 3 3 2 4 3 1 5 3 2 6 3 2 7

댓글 수: 3

Super close - you taught me a function that I'd never used before... but not quite the answer (see how colC doesn't restart when either ColA or ColB change).... but I think you're on the right track and I'll try to work from what you've showed
Also:
DAT = array2table([
"A" "a" "1"
"A" "a" "2"
"B" "a" "3"
"C" "a" "3"
"C" "b" "5"
"C" "a" "4"
"C" "b" "6"
"C" "b" "7"
], 'Var', ["ColA" "ColB" "ColC"]) ;
for i = 1:3
[~,~,DAT.(i)] = unique(DAT.(i)) ;
end
DAT
DAT = 8×3 table
ColA ColB ColC ____ ____ ____ 1 1 1 1 1 2 2 1 3 3 1 3 3 2 5 3 1 4 3 2 6 3 2 7
Yep, grp2idx looks like a replicate of the 3rd output to unique (which is what I've always used for this type of operation) with grp2idx() just not having the same features to sort in chosen ordering/stability.
I'm still not able to produce the cascading/resetting set of tickers behavior without writing an explicit set of loops that match the number of columns... tricky one I think.

댓글을 달려면 로그인하십시오.

카테고리

도움말 센터File Exchange에서 Shifting and Sorting Matrices에 대해 자세히 알아보기

제품

릴리스

R2022a

태그

질문:

2022년 6월 29일

댓글:

2022년 6월 29일

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by