Counting in one column that is conditional on another column

For each cell (or "trial") in the variable trials (attached):
I'd like to count the number of 1's in column 4 that is dependent on certain conditions in column 2 for each trial.
Conditions saved in their own variable:
Count 1's in column 4 if column 2 is between 0 and 4 (less than 4, not equal to)
Count 1's in column 4 if column 2 is between 4 and 5 (less than 5, not equal to)
Count 1's in column 4 if column 2 is between 5 and 6 (less than 6, not equal to)
Count 1's in column 4 if column 2 is between 6 and 7 (less than 7, not equal to)
Count 1's in column 4 if column 2 is between 7 and end

 Respuesta aceptada

per isakson
per isakson el 2 de Abr. de 2021
Editada: per isakson el 2 de Abr. de 2021
Does this do what you look for?
%%
limits = { [0;4], [4;5], [5;6], [6;7], [7;inf] };
%% some simple test data
trials = {[ 0, 2, 0, 1, 0, 0, 0
0, 2, 0, 0, 0, 0, 0
0, 5, 0, 1, 0, 0, 0
0, 5, 0, 0, 0, 0, 0
0, 5, 0, 1, 0, 0, 0
0, 5, 0, 0, 0, 0, 0
0, 9, 0, 1, 0, 0, 0 ]};
%%
fh = @(trial,lim) sum( (trial(:,4)==1) & (lim(1)<=trial(:,2) & trial(:,2)<lim(2)), 1 );
%%
counts = zeros( numel(trials), numel(limits) );
for rr = 1 : numel(trials)
for cc = 1 : numel(limits)
counts(rr,cc) = fh( trials{rr}, limits{cc} );
end
end
Inspect
>> counts
counts =
1 0 2 0 1
Yes, sum() can operate on logicals
>> sum([true,true,false])
ans =
2

10 comentarios

Mirthand
Mirthand el 2 de Abr. de 2021
Editada: Mirthand el 2 de Abr. de 2021
When I inspect counts in the data it returns a 56 x 5 double where the first row
is:
29 0 0 0 0
It seems like it is summing column 4 for each trial but not counting within the limits. The first number 29 is correct for the total 1's in that trial column.
Edit: maybe its because in my file I have zeros in my data and in your sample test data there is not zeros in the second column. For example my data in second column:
[0;0;3;0;3;0;3;0;0;0;4;0]
per isakson
per isakson el 3 de Abr. de 2021
Editada: per isakson el 3 de Abr. de 2021
The matrix in the first cell of trials has nearly five thousand rows, which makes it hard to inspect visually. However, I tried and I think that [29 0 0 0 0] is the correct result.
>> sum( trials{1}(:,2)==1 & trials{1}(:,4)==1 )
ans =
29
>> sum( trials{1}(:,2)==1 )
ans =
29
ans==29 in both cases. Thus trials{1}(:,2)==1 when trials{1}(:,4)==1
With
trials = {[ 0, 2, 0, 1, 0, 0, 0
0, 2, 0, 0, 0, 0, 0
0, 0, 0, 0, 0, 0, 0
0, 5, 0, 1, 0, 0, 0
0, 5, 0, 0, 0, 0, 0
0, 5, 0, 1, 0, 0, 0
0, 0, 0, 0, 0, 0, 0
0, 5, 0, 0, 0, 0, 0
0, 0, 0, 0, 0, 0, 0
0, 6, 0, 1, 0, 0, 0 ]};
I get
>> counts
counts =
1 0 2 1 0
per isakson
per isakson el 3 de Abr. de 2021
Editada: per isakson el 3 de Abr. de 2021
[29,0,0,0,0] is not what you expected!
  • Did I misunderstand your question? Did you inspect my code?
  • The data, trials, does that deviate from your expectations?
In the entire matrix, counts, (calculated with my code) values differ from zero only in the first column. (That's the case even when I initiate counts with NaNs.)
I think the data, trials, deviated from my expectations in that there are 1's in the second column.
I think if I can convert all the 1's in the second column to 0's, the count code should work.
trials = {[ 0, 2, 0, 1, 0, 0, 0
0, 2, 0, 0, 0, 0, 0
0, 0, 0, 0, 0, 0, 0
0, 1, 0, 1, 0, 0, 0
0, 5, 0, 0, 0, 0, 0
0, 5, 0, 1, 0, 0, 0
0, 1, 0, 1, 0, 0, 0
0, 5, 0, 0, 0, 0, 0
0, 0, 0, 0, 0, 0, 0
0, 6, 0, 1, 0, 0, 0 ]};
clearvars, clc
%% data from your recent comment
trials = {[ 0, 2, 0, 1, 0, 0, 0
0, 2, 0, 0, 0, 0, 0
0, 0, 0, 0, 0, 0, 0
0, 1, 0, 1, 0, 0, 0
0, 5, 0, 0, 0, 0, 0
0, 5, 0, 1, 0, 0, 0
0, 1, 0, 1, 0, 0, 0
0, 5, 0, 0, 0, 0, 0
0, 0, 0, 0, 0, 0, 0
0, 6, 0, 1, 0, 0, 0 ]};
%% convert all the 1's in the second column to 0's,
num = trials{1};
num( num(:,2)==1, 2 ) = 0;
trials = {num};
%%
limits = { [0;4], [4;5], [5;6], [6;7], [7;inf] };
%%
fh = @(trial,lim) sum( (trial(:,4)==1) & (lim(1)<=trial(:,2) & trial(:,2)<lim(2)), 1 );
%%
counts = nan( numel(trials), numel(limits) );
for rr = 1 : numel(trials)
for cc = 1 : numel(limits)
counts(rr,cc) = fh( trials{rr}, limits{cc} );
end
end
and the result is
>> counts
counts =
3 0 1 1 0
>>
Mirthand
Mirthand el 5 de Abr. de 2021
Editada: per isakson el 5 de Abr. de 2021
For this data, I would want counts to be: 2 0 2 1 0
trials = {[ 0, 2, 0, 1, 0, 0, 0 bin 1
0, 2, 0, 0, 0, 0, 0
0, 0, 0, 0, 0, 0, 0
0, 1, 0, 1, 0, 0, 0 bin 1
0, 5, 0, 0, 0, 0, 0
0, 5, 0, 1, 0, 0, 0 bin 3
0, 1, 0, 1, 0, 0, 0 bin 1
0, 5, 0, 0, 0, 0, 0
0, 0, 0, 0, 0, 0, 0
0, 6, 0, 1, 0, 0, 0 ]}; bin 4
limits = { [0;4], [4;5], [5;6], [6;7], [7;inf] };
I would want the 7th line to be grouped with [5;6].
0, 1, 0, 1, 0, 0, 0
per isakson
per isakson el 5 de Abr. de 2021
Editada: per isakson el 5 de Abr. de 2021
"I would want counts to be: 2 0 2 1 0" and "I would want the 7th line to be grouped with [5;6]" That would break the rules given in your question. You would have to set up new rules.
(I have tagged the rows (in your most recent comment) to show to which bin each row contributes.)
You are right, I need to think carefully about how I want to change column 2 so that it works.
Thanks for your help again!

Iniciar sesión para comentar.

Más respuestas (1)

Steven Lord
Steven Lord el 2 de Abr. de 2021
Use discretize or findgroups to identify groups based on the values in column 2, then use groupsummary or splitapply to perform group processing on column 4 based on the groups you identified in the first step.

1 comentario

Would discretize work if there are zeros?
for example, I still want to group the third row with the group that is 2.
The 7th row, containing zero would also be grouped with 5.
trials = {[ 0, 2, 0, 1, 0, 0, 0
0, 2, 0, 0, 0, 0, 0
0, 0, 0, 0, 0, 0, 0
0, 5, 0, 1, 0, 0, 0
0, 5, 0, 0, 0, 0, 0
0, 5, 0, 1, 0, 0, 0
0, 0, 0, 0, 0, 0, 0
0, 5, 0, 0, 0, 0, 0
0, 0, 0, 0, 0, 0, 0
0, 6, 0, 1, 0, 0, 0 ]};

Iniciar sesión para comentar.

Categorías

Preguntada:

el 2 de Abr. de 2021

Comentada:

el 5 de Abr. de 2021

Community Treasure Hunt

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

Start Hunting!

Translated by