MATLAB Answers

0

Simpler code for aggregating data by sum

Asked by Clarisha Nijman on 10 Jan 2019
Latest activity Commented on by Clarisha Nijman on 12 Jan 2019
Hello,
given matrix A: A=[4 0.5;4 0.25;1 0.125; 2 0.2;4 0.6;3 0.2; 1 2/3; 2 1; 2 1/16;4 0.5]
asked: Aggregate data in first column by sum
desired result:
1.0000 0.7917
2.0000 1.2625
3.0000 0.2000
4.0000 1.8500
I composed a code, but it work half, it can not make the data unique. So it fails at : G=unique(List)
Can somebody tell me why it fails at that point? And is there a more straight forward code for this whole proces? Maybe inbuilt functions? Can I get some feedback pls?
This is my code:
List=[];
% Make list unique
for i=1:size(A,1)
F=A(A(:,1)==A(i,1),:); %subsetting all rows
ElementList=[A(i,1) sum(F(:,2))]; %adding the sum of the subset to a row
List=[List; ElementList] % saving row plus its aggregated sum to a list
end
G=unique(List) %making the list unique
kind regards,

  3 Comments

Try this:
G = findgroups(A(:,1));
A=[4 0.5;4 0.25;1 0.125; 2 0.2;4 0.6;3 0.2; 1 2/3; 2 1; 2 1/16;4 0.5]
func = @(x)sum(x);
Y = splitapply(func,A(:,2),G);
[unique(G) Y]
ans =
1.0000 0.7917
2.0000 1.2625
3.0000 0.2000
4.0000 1.8500
Or simply:
A = [4 0.5;4 0.25;1 0.125; 2 0.2;4 0.6;3 0.2; 1 2/3; 2 1; 2 1/16;4 0.5];
B = splitapply(@sum,A(:,2),A(:,1));
The result is:
>>[unique(A(:,1)), B]
ans =
1.0000 0.7917
2.0000 1.2625
3.0000 0.2000
4.0000 1.8500
Thank you dear friends!!! Suggestion woks perfect!

Sign in to comment.

1 Answer

Answer by OCDER
on 10 Jan 2019
 Accepted Answer

A=[4 0.5;4 0.25;1 0.125; 2 0.2;4 0.6;3 0.2; 1 2/3; 2 1; 2 1/16;4 0.5]
Results = [unique(A(:, 1)), accumarray(A(:, 1), A(:, 2))];
Results =
1.0000 0.7917
2.0000 1.2625
3.0000 0.2000
4.0000 1.8500

  4 Comments

Show 1 older comment
Dear all,
I want to apply your instructions in my case, but do not fully understand how to use these instructions. It regards aggregating rows based of three columns by sum of the forth column.
% a simplified version of my case looks like:
A=[2.0000 3.0000 4.0000 0.01;
2.0000 3.0000 4.0000 0.05;
3.0000 2.0000 4.0000 0.01;
3.0000 4.0000 2.0000 0.02;
1.0000 2.0000 3.0000 0.03;
2.0000 3.0000 4.0000 0.00;
1.0000 2.0000 3.0000 0.02;
2.0000 3.0000 4.0000 0.01;
2.0000 3.0000 4.0000 0.01;
3.0000 2.0000 4.0000 0.07];
% Aggregated the first three columns by sum of the 4th column
% The result should be:
E= [1.0000 2.0000 3.0000 0.05;
2.0000 3.0000 4.0000 0.08;
3.0000 2.0000 4.0000 0.10];
This is how I tried to adapt your suggestions. But I am getting errors.
% % Code 1:
G = findgroups(A(:,1:3));
func = @(x)sum(x);
Y = splitapply(func,A(:,4),G);
E=[unique(G) Y];
% Code 2:
B = splitapply(@sum,A(:,4),A(:,1:3));
E=[unique(A(:,1:3)), B]
% Code 3:
E = [unique(A(:, 1:3)), accumarray(A(:, 1:3), A(:, 4))];
Can I have your feedback?
Check your results, as you have [3 4 2] unique combo.
A=[2.0000 3.0000 4.0000 0.01;
2.0000 3.0000 4.0000 0.05;
3.0000 2.0000 4.0000 0.01;
3.0000 4.0000 2.0000 0.02;
1.0000 2.0000 3.0000 0.03;
2.0000 3.0000 4.0000 0.00;
1.0000 2.0000 3.0000 0.02;
2.0000 3.0000 4.0000 0.01;
2.0000 3.0000 4.0000 0.01;
3.0000 2.0000 4.0000 0.07];
[UnqVal, ~, UnqGrpNum] = unique(A(:, 1:3), 'rows');
E = [UnqVal, accumarray(UnqGrpNum, A(:, end))];
E =
1.0000 2.0000 3.0000 0.0500
2.0000 3.0000 4.0000 0.0800
3.0000 2.0000 4.0000 0.0800
3.0000 4.0000 2.0000 0.0200
Ok I see, you have to assign the unique groups a number, such that you can refer to them in the accumarray function. If would never come up with such a good idea. I worked with for loops and the code runs very very long. I indeed missed the unique combo[3 4 2] in my results.
Thanks a lot!!!

Sign in to comment.