Clear Filters
Clear Filters

Automatically generate new matrices or arrays from unique values in matrix

6 views (last 30 days)
Hello,
I'm moderately experienced with programming, and I cannot believe how challenging I am finding this hurdle...
Suppose I have the following matrix:
a = [1,1;1,2.5;1,3;2,2;2,2;2,2;3,10;3,11;3,14;3,19;4,9]
and the first column represents a unique site or subject that I need to analyze separately. How can I make, in this case, 4 new matrices or arrays, within the workspace so that I have products that look like this:
site1 = [1,1;1,2.5;1,3]
site2 = [2,2;2,2;2,2]
My real data is more advanced than this, of course, but I cannot seem to figure out how to separate the data into separate sub-data sets based on a unique values. This seems to be a simple problem but I've tried looking at for-loops, the command 'unique', etc. and am getting absolutely nowhere.
Thanks ahead of time,
Ryan

Accepted Answer

Sean de Wolski
Sean de Wolski on 26 Jan 2012
Edited: the cyclist on 24 May 2017
B = accumarray(a(:,1),a(:,2),[],@(x){x})
Using it directly like this, the index will be the leading number. Why you would need to replicate it, I don't know but it could be done easily. I.e:
B=
[3x1 double]
[3x1 double]
[4x1 double]
[ 4]
Thus the first 3x1 could get three ones because it's the first index, etc. Let me know if you need more clarification.
EDIT (from the cyclist): Be sure to see Stephen Cobeldick's comment to this answer, which solves this entirely.
  2 Comments
Stephen23
Stephen23 on 24 May 2017
Edited: Stephen23 on 24 May 2017
It is also easy to use accumarray to get the entire rows, which is also simpler than the accepted answer:
>> a = [1,1;1,2.5;1,3;2,2;2,2;2,2;3,10;3,11;3,14;3,19;4,9];
>> C = accumarray(a(:,1),(1:size(a,1))',[],@(r){a(r,:)});
>> C{:}
ans =
1 1
1 2.5
1 3
ans =
2 2
2 2
2 2
ans =
3 10
3 11
3 14
3 19
ans =
4 9
the cyclist
the cyclist on 24 May 2017
I've unaccepted my answer and accepted this one, which is indeed syntactically simpler. However, if one is having a difficult time understanding the underlying "magic" of accumarray, I would encourage you to look at my alternative solution, which exposes the algorithm more clearly.

Sign in to comment.

More Answers (1)

the cyclist
the cyclist on 26 Jan 2012
There are many ways to slice this particular cat. Here is one way I typically use. I've tried to use descriptive variable names, to help you understand the logic of what I am doing.
a = [1,1;1,2.5;1,3;2,2;2,2;2,2;3,10;3,11;3,14;3,19;4,9];
[uniqueFirstColumnValues,indexToUnique,indexFromUniqueBackToAll] = unique(a(:,1));
numberUniqueValues = numel(uniqueFirstColumnValues);
subsetData = cell(numberUniqueValues,1);
for nu = 1:numberUniqueValues
indexToThisUniqueValue = (indexFromUniqueBackToAll==nu);
subsetData{nu} = a(indexToThisUniqueValue,:);
end
Note that each subset of data is a differently sized matrix, so I chose to store the results in a cell array.

Community Treasure Hunt

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

Start Hunting!