Reputation: 311
This is continuation of my previous questions (one, two) and this is my real problem I have an array of data:
a b c d
0 1 2 5
0 1 7 1
0 0 5 5
0 0 0 1
0 1 0 2
as you can see i want abc to be combine and in one column, just like this:
abc d
012 5
017 1
005 5
000 1
010 2
so i will now have 2 columns abc and d
next i want to count repeated values of d, add it up and combined those corresponding abc, see below
abc d
012,005 10
017,010 2
010 5
so as you can see, 012, and 005 combine because they have the same value of d, and their d add up so it become 10, so how i can do that? this is my real problem please help thanks.
Upvotes: 1
Views: 89
Reputation: 25232
A = [...
0 1 2 5;
0 1 7 1;
0 0 5 5;
0 0 0 1;
0 1 0 2 ]
%// column for identification
subs = A(:,4);
%// get order for sorting output
order = unique(subs,'stable')
%// get strings from numbers
abc = cellstr(reshape(sprintf('%i',A(:,1:3)),size(A(:,1:3))))
%// gather abc
groups = accumarray(subs,1:numel(subs),[],@(x) {abc(x)})
%// sum counts
counts = accumarray(subs,subs,[],@sum)
%// output
out = [groups num2cell(counts)]
%// reorder output
out = out(order,:)
%// filter output
out(find(~counts(order)),:) = []
out =
{2x1 cell} [10]
{2x1 cell} [ 2]
{1x1 cell} [ 2]
with for example
out{1,1} =
'005'
'012'
As you see out{1,1}
is still not in the correct order. The reason is that accumarray
is not stable. To solve it, use the function accumarrayStable
provided in the link:
function A = accumarrayStable(subs, val, varargin)
[subs(:,end:-1:1), I] = sortrows(subs(:,end:-1:1));
A = accumarray(subs, val(I), varargin{:});
end
and you will finally get:
out{1,1} =
'012'
'005'
Upvotes: 4