Reputation: 2299
I have a question on a piece of code in Matlab. Suppose we have a matrix
A
of dimension mx4
A=[ 2 3 4 |1
2 3 4 |0
1 1 1 |0
1 1 1 |1
9 1 0 |0
9 1 0 |0
9 1 0 |1]
I want to order the rows with the first three elements of the row equal with respect to the fourth column in descending order. Hence, I want to get
B=[ 2 3 4 |1
2 3 4 |0
1 1 1 |1
1 1 1 |0
9 1 0 |1
9 1 0 |0
9 1 0 |0]
Upvotes: 1
Views: 51
Reputation: 525
Se below a similar approach using splitapplay
(Introduced in R2015b)
A=[ 2 3 4 1
2 3 4 0
1 1 1 0
1 1 1 1
9 1 0 0
9 1 0 0
9 1 0 1];
% Map first 3 columns to a single value
aux = str2num(strcat(num2str(A(:,1)),num2str(A(:,2)),num2str(A(:,3))));
% Find groups
G = sort(findgroups(aux));
% Sort groups of same value in descending order with respect to column 4
sorted = splitapply(@(x,y) {[dec2base(x,10)-'0',sort(y,'descend')]}, aux, A(:,4), G );
sorted = cell2mat(sorted)
sorted =
2 3 4 1
2 3 4 0
1 1 1 1
1 1 1 0
9 1 0 1
9 1 0 0
9 1 0 0
Upvotes: 1
Reputation: 65430
One way to accomplish this would be to create an M x 2 matrix that you can sort using sortrows
. sortrows
sorts the first column and then uses the second column to settle any ties. The first column will be an index used to represent unique combinations of the first three columns of A
.
For your example data, the first column would look like this.
[~, ~, inds] = unique(A(:,1:3), 'rows', 'stable');
inds =
1
1
2
2
3
3
3
Then, the second column is the column that you want to sort (your 4th column).
cat(2, inds, A(:,4))
1 1
1 0
2 0
2 1
3 0
3 0
3 1
Now we want to use sortrows
on this and sort the first column in ascending order and the second column in descending order.
sorted = sortrows(cat(2, inds, A(:,4)), [1 -2])
1 1
1 0
2 1
2 0
3 1
3 0
3 0
This second column corresponds to the desired 4th column that you've shown in B
. So let's simply concatenate it with the first three columns of A
to create B
.
B = cat(2, A(:,1:3), sorted(:,2))
2 3 4 1
2 3 4 0
1 1 1 1
1 1 1 0
9 1 0 1
9 1 0 0
9 1 0 0
So bringing that all together we get the following.
[~, ~, inds] = unique(A(:,1:3), 'rows', 'stable');
sorted = sortrows(cat(2, inds, A(:,4)), [1 -2]);
B = cat(2, A(:,1:3), sorted(:,2));
Upvotes: 1