# Get mean and stdev from all values

5 views (last 30 days)
Dion Theunissen on 3 Jun 2021
Commented: Steven Lord on 3 Jun 2021
Hi,
I have a list like below. in the first column I have values from 0 to 91 (there can miss values).
0 3
0 4.50000000000000
0 1.37500000000000
0 5
0 3
0 0.838961038961039
0 2.80000000000000
1 1.50000000000000
1 0.555555555555556
1 1.71428571428571
1 3.38666666666667
1 4
1 3.38666666666667
2 1.73684210526316
2 1
2 1.30769230769231
2 2.73333333333333
2 1
2 2
I want to calculate the mean and standard deviation for all of these values if they exist.
How can I realise this? Now I have the folowing:
clear all; clc; close all;
indices = find(standaard(:,1)==0);
standaard(indices,:) = [];
indices = find(standaard(:,2)>8);
standaard(indices,:) = [];
standaard(:,1) = round(standaard(:,1));
standaard = sortrows(standaard,1);
c = {};
for i = 0:5:85
if i == 0
lower = find(standaard(:,1) == i);
n = i+5;
upper = find(standaard(:,1) == n);
elseif i>1
lower = find(standaard(:,1) == i+1);
n = i+5;
upper = find(standaard(:,1) == n);
end
tab = standaard(lower(1):upper(end),:);
c{i+1} = tab;
end
referent2 = []
for j = 1:5:86
data = cell2mat(c(j));
referent(1,1) = data(1,1);
referent(1,2) = mean(data(:,2));
referent(1,3) = std(data(:,2));
referent2 = [referent2;referent]
end
snelheid = linspace(min(referent2(:,1)),max(referent2(:,1)));
a1 = interp1(referent2(:,1), referent2(:,2:end), snelheid, 'makima');
verbruik = a1(:,1);
upper = a1(:,1)+a1(:,2);
lower = a1(:,1)-a1(:,2);
figure
hold on
plot(snelheid, verbruik, '-b');
plot(snelheid, upper,'-r');
plot(snelheid, lower,'-g');
How can i change this script that i get the mean and stdev from all existing values?
thanks
##### 2 CommentsShow 1 older commentHide 1 older comment
Dion Theunissen on 3 Jun 2021
Indeed, the blocks have not the same size and are sorted in column 1.
So i need to check for each value from 1 untill 91 the mean and standard deviation

DGM on 3 Jun 2021
Edited: DGM on 3 Jun 2021
If column 1 is sorted:
% build test array
idx = repelem(1:10,randi(6,10,1));
idx = idx(1:20);
D = [idx.' rand(20,1)]; % the test array
% find length of blocks
blocklengths = diff([0 find(diff(idx)) numel(idx)]);
% split and process
C = mat2cell(D(:,2),blocklengths,1);
bkmean = cellfun(@mean,C)
bkmean = 6×1
0.8030 0.6236 0.4651 0.2942 0.4628 0.6299
bkstd = cellfun(@std,C)
bkstd = 6×1
0.1993 0.3422 0.1443 0.2592 0.5516 0.0849

Stephan on 3 Jun 2021
Edited: Stephan on 3 Jun 2021
Use a table and then use findgroups combined with splitappy. This will allow you to solve the problem with a few lines of code. This will also work if the columns are not sorted.
Steven Lord on 3 Jun 2021
findgroups can operate on numeric data as well as tabular data.
But rather than call those two functions sequentially, I'd probably just use groupsummary.
X = [0 3;
0 4.50000000000000;
0 1.37500000000000;
0 5;
0 3;
0 0.838961038961039;
0 2.80000000000000;
1 1.50000000000000;
1 0.555555555555556;
1 1.71428571428571;
1 3.38666666666667;
1 4;
1 3.38666666666667;
2 1.73684210526316;
2 1;
2 1.30769230769231;
2 2.73333333333333;
2 1;
2 2];
[M, BG] = groupsummary(X(:, 2), X(:, 1), @mean)
M = 3×1
2.9306 2.4239 1.6296
BG = 3×1
0 1 2
check = mean(X(X(:, 1)== 1, 2)) % This is the same as M(BG == 1)
check = 2.4239
S = groupsummary(X(:, 2), X(:, 1), @std)
S = 3×1
1.5037 1.3554 0.6728
MS = groupsummary(X(:, 2), X(:, 1), {@mean, @std}) % Compute M and S simultaneously
MS = 3×2
2.9306 1.5037 2.4239 1.3554 1.6296 0.6728

### Categories

Find more on Data Type Conversion in Help Center and File Exchange

R2021a

### Community Treasure Hunt

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

Start Hunting!