LoginSignup
1
1

More than 5 years have passed since last update.

bcで基本統計量を計算する

Posted at

はじめに

基本統計量を計算するbcコマンドのスクリプトです。

スクリプトと出力形式

【bcスクリプト】
basic_statistics.bc
define set_scale(x, s) {
    auto old_scale
    old_scale = scale
    scale = s
    x /= 1  #scale 設定
    scale = old_scale
    return (x)
}
define round(d, s) {
    auto temp;
    if(scale(d) < s) return (set_scale(d, s))
    temp = (d - set_scale(d, s)) * (10^(s+1))
    if(temp > 5) d += (1/(10^s))
    return (set_scale(d,s))
}
define power(d, i) {
    return(e(i*l(d)))
}

scale = 100
n = read()
for(i = 0; i < n; i++){
    ds[i] = read()
}
sum = 0
for(i = 0; i < n; i++){
    d = ds[i]
    sum += d
    if( i == 0) {
        max = d
        min = d
    } else {
        if(d > max){
            max = d;
        }
        if(d < min){
            min = d;
        }
    }
}
old_scale = scale
if( (n % 2) == 0) {
    scale = 0
    m1 = ds[n/2]
    m2 = ds[(n/2)+1]
    scale = old_scale
    med = (m1 + m2) / 2
} else {
    scale = 0
    med = ds[n/2]
    scale = old_scale
}
ave = sum / n
sum_dev2 = 0
sum_dev3 = 0
sum_dev4 = 0
for(i = 0; i < n; i++){
    dev = ds[i] - ave
    devs[i] = dev
    sum_dev2 += (dev * dev)
    sum_dev3 += (dev * dev * dev)
    sum_dev4 += (dev * dev * dev * dev)
}
svar = sum_dev2 / n
ssd = sqrt(svar)
uvar = sum_dev2 / (n - 1)
usd = sqrt(uvar)

skew = (n /((n -1 ) * (n - 2))) * sum_dev3 / (usd^3)
kurt = ((n * (n + 1)) /((n -1 ) * (n - 2) * (n - 3))) * (sum_dev4 / (usd^4)) - ((3 * (n - 1)^2) / ((n - 2) * (n - 3)))

print "n = "; n
print "min = "; min
print "max = "; max
print "med = "; round(med, 20)
print "ave = "; round(ave, 20)
print "sum = "; round(sum, 20)
print "svar = "; round(svar, 20)
print "uvar = "; round(uvar, 20)
print "ssd = "; round(ssd, 20)
print "usd = "; round(usd, 20)
print "skew = "; round(skew, 20)
print "kurt = "; round(kurt, 20)


【出力形式】
n = データ数
min = 最小値
max = 最大値
med = 中央値
ave = 平均値
sum = データの総和
svar = 標本分散
uvar = 不偏分散
ssd = 標本標準偏差
usd = 不偏標準偏差    
skew = 歪度
kurt = 尖度

実行例

【データファイル】
q11.txt
1
2 2 2
3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
4 4
5

データは空白、タブ、改行で区切る。

【実行方法】
実行例
((cat q11.txt | wc -w); sort -g q11.txt) | bc -l -q basic_statistics.bc

データ数、データを空白、タブ、改行で区切って、bcにわたします。
中央値を計算する都合でデータは(数値として)ソートする必要があります。

実行結果
n = 30
min = 1
max = 5
med = 3.00000000000000000000
ave = 2.96666666666666666667
sum = 89.00000000000000000000
svar = .43222222222222222222
uvar = .44712643678160919540
ssd = .65743609744386733227
usd = .66867513545937177714
skew = .03679696392430356743
kurt = 4.50339722463221514906


環境

ホスト Windows10 COREi7
VM   VirtualBox バージョン 5.2.6 r120293 (Qt5.6.2)
     CentOS Linux release 7.4.1708 (Core)
GNU bash, バージョン 4.2.46(2)-release (x86_64-redhat-linux-gnu)
bc 1.06.95

おわりに

gawkで基本統計量を計算する」の検算用に作りました。
bcを選んだのは以下の理由によります。

  • 多倍長演算(Multiple Precision Arithmetic)をサポートしている
  • できるだけ標準的なもの(Unix/Linux)

データの読み込みにread()を使っています。bcはスクリプトの読み込みもread()も標準入力を使用しているので、shスクリプトとして作成するのが難しいです。数が少なければ環境変数で渡すのも手ですが、配列に渡すのは骨です。
以上

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1