# How to create a loop to sum across columns conditional on index matching?

13 views (last 30 days)
Matlabio on 25 Oct 2016
Commented: Matlabio on 3 Nov 2016
Hello, I have a binary matrix, with a corresponding index in the first column. For example:
A = [1 1 0 1 0 0 1 ..0]
1 0 0 0 1 1 0 ..1
2 ...
2 ...
2 ...
3 ...
[... ... ]
I want to sum all binary elements corresponding to 1 in the index, 2 in the index, etc. (i.e. index is =1 in the first and second row,so sum across each column, and so on). For the index, the number of corresponding rows with same index number varies across the dataset. I would appreciate all help and advice on how to do this.

Matt J on 25 Oct 2016
I want to sum all binary elements corresponding to 1 in the index, 2 in the index, etc. (i.e. index is =1 in the first and second row,so sum across each column, and so on).
You mean you want
sum A(i,1:A(i,1))
for each i?
Matlabio on 26 Oct 2016
I actually want to have a conditional sum - if index values match in any 2 or more rows, then sum each column in these rows to create a new summation vector. For instance: assume I have the following data matrix (with index in the 1st column): A = [1 1 0 0 0; 2 0 1 0 0; 2 0 0 0 1] In this case, for i =1, my result would be: 1 0 0 0; for i=2 => 0 1 0 1.

Chris Dischner on 25 Oct 2016
Assuming your index values are sequential:
aMax = max(A(:,1));
for i = 1:aMax
aSum(i,:) = sum(A(A(:,1) == i,:));
end
Will get you the sums. You can use modular arithmetic to get you to the bit representation
(eg, 1+1+1 = 3 ==> 3 mod 2 = 1

Matlabio on 26 Oct 2016
Thank you for your help! Actually some index values are non-sequential, but I believe that it should not pose a problem since in this case I should get all zeros in the resulting vector. I tried the code, but I'm not sure why it's not working in my case - I get the summation vector for each i with some values >1, which should not be the case since it's strictly binary and cannot exceed 1 in any column sum, for any i; so perhaps it somehow gives me a cumulative sum? Just to clarify, suppose I have the following data: A = [1 1 0 0 0; 2 0 1 0 0; 2 0 0 0 1] In this case, for i =1, my result would be: 1 0 0 0; for i=2 => 0 1 0 1
Matt J on 27 Oct 2016
I get the summation vector for each i with some values >1, which should not be the case since it's strictly binary and cannot exceed 1 in any column sum, for any i
The chances are excellent that it is the input data's fault and not the code's, i.e, that you have not successfully fulfilled the condition "cannot exceed 1 in any column sum, for any i". There is no reason this should be the case just because A(:,2:end) are all zeros and ones.

Matt J on 27 Oct 2016
Edited: Matt J on 27 Oct 2016
The following produces a result B, such that B(1,:) is the consolidation of all rows of A with index 1, B(2,:) all rows with index 2, etc...
m=size(A,1);
p=max(A(:,1));
B=sparse(A(:,1),1:m,1,p,m)*A(:,2:end);

#### 1 Comment

Matlabio on 3 Nov 2016
Thank you so much! You were actually right - there was an issue with the data which I have corrected, otherwise it worked perfectly.

Teja Muppirala on 28 Oct 2016
result = [unique(A(:,1)) grpstats(A(:,2:end),A(:,1),@any)] % Keep it binary
or
result = [unique(A(:,1)) grpstats(A(:,2:end),A(:,1),@sum)] % Take the sum