histogram, indices of values used from the vector for each class?

Hi,
could you help me to find out standard deviation calculated from the of 2nd column values coresponding to the histogram classes of the 1st column in a given 2 columns matrix?
for example in data
c1 = [ 1 3 2 1 3 1 2 2 3 3 2 2 ]'; c2 = [ 0.5 1.1 0.65 0.55 0.9 0.6 0.7 0.75 0.95 1 0.8 0.85]';
so for the group 1 standard deviation would be 0.05
histogram of c1 is easy, hist(c1, 1:1:3); or [n, xout] = hist(c1, 1:1:3); but how to get indices of histogram c1 groups (c1_i1) which could be used to calculate std of c2 values? c2_std1 = std(c2(c1_i1))? is it currently possible by using histogram?
one solution is by using find (not histogram), e.g. c1_i1 = find (0 <c1 & c1 < 2); c2_std1 = std(c2(c1_i1))
but this is quite complicated for large matrices whith many classes of 1st column.
Thanks, Boris

 Réponse acceptée

If you have access to the functions in the Statistics Toolbox, I think GRPSTATS may help you
c1 = [ 1 3 2 1 3 1 2 2 3 3 2 2 ]';
c2 = [ 0.5 1.1 0.65 0.55 0.9 0.6 0.7 0.75 0.95 1 0.8 0.85]';
grpstats(c2,c1,'std')
The result is the standard deviation for each group:
ans =
0.0500
0.0791
0.0854

1 commentaire

Hi,
thanks for the answer. Better example of my c1 data is in decimals e.g.
c1d = [ 0.3 2.4 1.3 0.7 2.6 0.9 1.8 1.5 2.2 2.8 1.7 1.2 ]';
groups 1,2,3 should be defined as in c1, and then yes either grpstats or accumarray can be used.
How can c1d values be redefined as c1 classes?

Connectez-vous pour commenter.

Plus de réponses (2)

accumarray(c1,c2,[],@std)
I have it running about 3x faster than grpstats too:
c1 = [ 1 3 2 1 3 1 2 2 3 3 2 2 ]';
c2 = [ 0.5 1.1 0.65 0.55 0.9 0.6 0.7 0.75 0.95 1 0.8 0.85]';
c1 = repmat(c1,100,1);
c2 = repmat(c2,100,1);
t1 = 0;
t2 = 0;
for ii = 1:100
tic
grpstats(c2,c1,'std');
t1 = t1+toc;
tic
accumarray(c1,c2,[],@std);
t2 = t2+toc;
end

2 commentaires

thanks,
accumarray is truly faster but i have to solve one more thing. c1 data example was simplified too much.
classes are not so obvious, but are rather in decimals like:
c1d = [ 0.3 2.4 1.3 0.7 2.6 0.9 1.8 1.5 2.2 2.8 1.7 1.2 ]';

Connectez-vous pour commenter.

thank you Teija and Sean, the first part can work as in following example
c1d = [ 0.3 2.4 1.3 0.7 2.6 0.9 1.8 1.5 2.2 2.8 1.7 1.2 ]';
%convert c1d to clases 1,2,3 by using %[n,bin] = histc(x,edges) counts the number of values in vector x % that fall between the elements in the edges vector and also % returns an index matrix bin.
[n, bin] = histc(c1d, [0 1 2 3 ]);
% bin would be the same as c1 in previous example:
[bin c1]
ans =
1 1
3 3
2 2
1 1
3 3
1 1
2 2
2 2
3 3
3 3
2 2
2 2
% then both grpstats or accumarray will calculate statistics (std)
grpstats(c2,bin,'std')
ans =
0.0500
0.0791
0.0854
accumarray(bin,c2,[],@std)
ans =
0.0500
0.0791
0.0854

Community Treasure Hunt

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

Start Hunting!

Translated by