How can I sort the output matrix according to the prescribed order in a column?

Hi all,
I have my output matrix data in nx3 dimension.
Now I wish to sort these data,neither in the ascending nor descending order in a column, but according to the prescribed order in a column.
For example, if my matrix is
1 0.5 0.8
10 0.6 0.5
11 0.3 0.1
13 0.1 0.8
Now I want to sort the matrix according to the prescribed order of "11 10 1 13" in column 1, that is, the sorted matrix is expected to be
11 0.3 0.1
10 0.6 0.5
1 0.5 0.8
13 0.1 0.8
What is your suggestion?
Thanks in advance.
Fei

Answers (2)

Presuming you have (or can generate) the desired order vector, then it's pretty much trivial--just find where they're located in the original array. This assumes no ties.
Mat
>> ix=[11 10 1 13]';
%
%[erratum -- dpb]
% following returns the locations in the index vector, NOT in the array
>> [~,ib]=ismember(M(:,1),ix); % INCORRECT original posting
%
% It was intended to interchange the order of arguments as follows
>> [~,ib]=ismember(ix,M(:,1)); % CORRECT
%[ end erratum]
>> M(ib,:)
ans =
11.0000 0.3000 0.1000
10.0000 0.6000 0.5000
1.0000 0.5000 0.8000
13.0000 0.1000 0.8000
>>

2 Comments

Thanks dpb.
This works efficiently, however I think there might be an error in your code.
[~,ib]=ismember(M(:,1),ix)
returns ib which is the location of M(:,1) found in ix, e.g., '1' is in ix(3), therefore you have ib=3; then you output M(3,:) as the first row but this is not logical because no one tells us M(3,:) should be in the first row, although the final result is right by chance.
Now suppose I add a 5th row in my original matrix, say the matrix is
1 0.5 0.8
10 0.6 0.5
11 0.3 0.1
13 0.1 0.8
9 0 15
Now I wish to output in the order like [[11 9 10 1 13], using the code above will yield
13.0000 0.1000 0.8000
11.0000 0.3000 0.1000
1.0000 0.5000 0.8000
9.0000 0 15.0000
10.0000 0.6000 0.5000
I think the right one is
[~,ib]=ismember(ix,M(:,1))
We output the location of ix found in M(:,1), and then sequentially print the data according to the location. For instance, '11' should be in the first row according to the prescribed order, and it is M(3:1), therefore we have ib=3 and print M(3,:) in the first row.
M=[1 0.5 0.8
10 0.6 0.5
11 0.3 0.1
13 0.1 0.8
9 0 15];
ix=[11 9 10 1 13];
[lia,locb]=ismember(ix,M(:,1))
M(locb,:)
output is
lia =
1 1 1 1 1
locb =
3 5 2 1 4
ans =
11.0000 0.3000 0.1000
9.0000 0 15.0000
10.0000 0.6000 0.5000
1.0000 0.5000 0.8000
13.0000 0.1000 0.8000
_This works efficiently, however I think there might be an error in your code.
[~,ib]=ismember(M(:,1),ix)
...the right one is
[~,ib]=ismember(ix,M(:,1)) _
That is correct, sorry--I did inadvertently swap the order of which is in which in the argument list and by chance the original sample case didn't show it up...

Sign in to comment.

a = [1 0.5 0.8
10 0.6 0.5
11 0.3 0.1
13 0.1 0.8
9 0 15];
b = [11 9 10 1 13];
[~,ia] = sort(a(:,1));
[~,ib] = sort(b);
out = a(ia(ib),:);
ADD
[~,ia] = sort(a(:,1));
[~,ib] = sort(b);
ii = sortrows([ia(:),ib(:)],2);
out = a(ii(:,1),:);

2 Comments

Thank you Andrei.
This seems working well also. However I don't understand why
a = [1 0.5 0.8
10 0.6 0.5
11 0.3 0.1
13 0.1 0.8
9 0 15];
[~,ia] = sort(a(:,1))
would give
ia =
1
5
2
3
4

Sign in to comment.

Categories

Asked:

Fei
on 6 Jul 2013

Community Treasure Hunt

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

Start Hunting!