Operating on One Column Based on Another

So I've run into a buzzsaw of a problem. I have a m x n numeric matrix (no strings, etc.) and two columns are of interest. Column 1 looks like this:
A = [1;1;1;1;2;2;2;3;3;3;3;3;4;4;4;5;5;5]
Next, column 2:
B = [1;2;3;4;5;6;7;8;9;10;11;12;13;14;15;16;17;18];
What want to do is look at where values of A are equal and operate on those values in the same position in B. In other words, A(1:4) = 1 so I want to add together (or standard deviation, variance, etc.) B(1:4). Then, I want to move on to the next set of equal values of A and operate on the corresponding positions of B, and so on. Once values have been added together, I want to compare the result against a tolerance value and if the sum falls outside of the value, I want to delete those rows.
The problem I'm running into is that all of the comparison methods I've tried automatically dismiss the last value in B. So, where A(5:1) doesn't equal A(4:1), I'll get a sum, let's say, for B(1:3) instead of B(1:4). For example, one method I tried was:
a = unique(matrix(:,col_A))
tol = 5;
for i = 1:length(matrix)
idx = find(matrix(i,col_A) == a);
if isequal(matrix(i),idx)
std_dev = std(matrix(m,B));
if std_dev < tol
matrix(matrix(m,:)) = [];
end
end
end
At first, because of how isequal works, the algorithm discards A(4,1) doesn't equal A(5,1). I understand why this is happening, but I can't think of a viable solution. I tweaked it a bit, but now when I run the algorithm as written above, nothing happens at all.
If I was unclear at any point, don't hesitate to let me know. Any help you all can provide would be most appreciated!

 Akzeptierte Antwort

Stephen23
Stephen23 am 27 Apr. 2018
Bearbeitet: Stephen23 am 27 Apr. 2018

1 Stimme

You should look into accumarray:
>> A = [1;1;1;1;2;2;2;3;3;3;3;3;4;4;4;5;5;5];
>> B = [1;2;3;4;5;6;7;8;9;10;11;12;13;14;15;16;17;18];
>> S = accumarray(A,B,[],@sum)
S =
10
18
50
42
51
>> S(A)
ans =
10
10
10
10
18
18
18
50
50
50
50
50
42
42
42
51
51
51
If the values of A are not consecutive integers starting from one, then use unique first and use its third output argument.

3 Kommentare

Jeremy
Jeremy am 27 Apr. 2018
Bearbeitet: Jeremy am 27 Apr. 2018
Stephen - First, thank you very much for your reply. This looks like exactly what I need. Here's a follow-up question if you have time: these are the vectors I'm actually working with
A = [10517;10517;10517;10517;29272;29272;29272;29272;29272;35942; ...
35942;35942;35942;35942;39017;39017;39017;39017]
B = [-25;37;-34;69;-20;-21;-22;-23;-25;5;6;8;5;4;-17;-20;-25;-23]
In order to make things work, I had to rewrite A to be:
new_A = [1;1;1;1;2;2;2;2;2;3;3;3;3;3;4;4;4;4]
Leaving it in the original configuration produced a 39017x1 matrix of 0s, which was extremely unhelpful. Further, I had to hardcode new_A so things would work as advertised. Is there a clever way I can substitute values of new_A into A so I don't have to hardcode anything? Also, I wasn't following your advice regarding the use of the 'unique' function, so if that has an impact on things, I wouldn't know at this point.
Thanks a lot for your time and help!
Stephen23
Stephen23 am 28 Apr. 2018
Bearbeitet: Stephen23 am 28 Apr. 2018
[~,~,newA] = unique(A,'stable')
Jeremy
Jeremy am 28 Apr. 2018
You are my new hero. That is perfect and I sincerely appreciate your time. Take care and have a good weekend!

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (0)

Gefragt:

am 27 Apr. 2018

Kommentiert:

am 28 Apr. 2018

Community Treasure Hunt

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

Start Hunting!

Translated by