standard deviation of an arbitrary number of numbers using bc or other standard utilities
Using awk:
standardDeviation=$(
echo "$myNumbers" |
awk '{sum+=$1; sumsq+=$1*$1}END{print sqrt(sumsq/NR - (sum/NR)**2)}'
)
echo $standardDeviation
Using perl :
#!/usr/bin/env perl
use strict; use warnings;
use Math::NumberCruncher;
my @data = qw/
0.556
1.456
45.111
7.812
5.001
/;
print Math::NumberCruncher::StandardDeviation(\@data);
Output
16.7631
Population standard deviation:
jq -s '(add/length)as$a|map(pow(.-$a;2))|add/length|sqrt'
ruby -e'a=readlines.map(&:to_f);puts (a.map{|x|(x-a.reduce(:+)/a.length)**2}.reduce(:+)/a.length)**0.5'
jq -s '(map(.*.)|add/length)-pow(add/length;2)|sqrt'
awk '{x+=$0;y+=$0^2}END{print sqrt(y/NR-(x/NR)^2)}'
In awk
, ^
is in POSIX but **
is not. **
is supported by gawk
and nawk
but not by mawk
.
Sample standard deviation (the first two commands are the same as the first two commands above, but length
was replaced with length-1
):
jq -s '(add/length)as$a|map(pow(.-$a;2))|add/(length-1)|sqrt'
ruby -e'a=readlines.map(&:to_f);puts (a.map{|x|(x-a.reduce(:+)/a.length)**2}.reduce(:+)/(a.length-1))**0.5'
R -q -e 'sd(scan("stdin"))'
Or use GNU Octave (which can much more than simple std):
standardDeviation="$(echo "${myNumbers}" | octave --eval 'disp(std(scanf("%f")))')"
echo $standardDeviation
Outputs
18.742