Filtering rows of a matrix based on some columns

This is an overview of the problem I am having:
Example matrix:
[100 101 32.5;
200 205 50.0;
201 201 0.47;
100 101 60.0;
200 205 25.0]
My actual matrix is thousands of rows long.
And I want to be able to find all rows with common entries in column 1 & 2 AND add corresponding values in column three together. i.e I want something like(adding row 1 & 4 since they have common elements on column 1 & 2; similarly row 2 &5):
[100 101 92.5; 200 205 75.0]
And I want to create a new matrix for any rows with same values on first two columns:
[201 201 0.47]
My data will have a mixture of these two row types.
Thank you

 Accepted Answer

[ua1, junk1, b1] = unique( A(:,1) );
[ua2, junk2, b2] = unique( A(:,2) );
tB = accumarray( [b1(:), b2(:]], A(:,3), [], @sum, NaN);
idx = find( ~isnan(tB) );
[r, c] = sub2idx( size(tB), idx);
B = [ua1(r(:)), ua2(c(:)), tB(idx(:)) ];
C = A( A(:,1) == A(:,2), : );

5 Comments

Walter, everything else seems to work other than [r, c] = sub2idx( size(tB), idx)
sub2idx is undefined ! Thanks again.
subs2idx() instead. I tend to drop the "s" at 3 AM!
I still get "Undefined function or method 'subs2idx' for input arguments of type double" with subs2idx
Sorry, really it should be ind2sub()
http://www.mathworks.com/help/techdoc/ref/ind2sub.html

Sign in to comment.

More Answers (1)

[a,b,b] = unique( A(:,1:2),'rows' );
B = [a,accumarray(b,A(:,3))];
C = B(abs(diff(B(:,1:2),1,2)) < eps(100),:);

2 Comments

It works! But what if I wanted to collect averages instead of sums in the third column?
please read about 'accumarray'
B = [a,accumarray(b,A(:,3),[],@mean)];

Sign in to comment.

Community Treasure Hunt

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

Start Hunting!