単一のコマンドで数値リストの最小値、最大値、中央値、平均を取得する方法はありますか?

単一のコマンドで数値リストの最小値、最大値、中央値、平均を取得する方法はありますか?

ファイルには 1 行に 1 つずつ数値リストがあります。最小値、最大値はどのように求められますか?中央値そして平均価値? bashスクリプトで結果を使用したいです。

現在の状況は整数に関するものですが、最終的には浮動小数点ソリューションが役に立ちますが、単純な整数アプローチも問題ありません。

答え1

GNUと共にデータ混合:

$ printf '%s\n' 1 2 4 | datamash max 1 min 1 mean 1 median 1
4   1   2.3333333333333 2

答え2

あなたはそれを使用することができますRプログラミング言語

高速で汚れたRスクリプトは次のとおりです。

#! /usr/bin/env Rscript
d<-scan("stdin", quiet=TRUE)
cat(min(d), max(d), median(d), mean(d), sep="\n")

標準入力(パイプやリダイレクトなど)から読み取った特別なファイル名はどこに"stdin"ありますか?scan

stdinを介してデータをRスクリプトにリダイレクトできるようになりました。

$ cat datafile
1
2
4
$ ./mmmm.r < datafile
1
4
2
2.333333

浮動小数点でも動作します。

$ cat datafile2
1.1
2.2
4.4
$ ./mmmm.r < datafile2
1.1
4.4
2.2
2.566667

Rスクリプトファイルを作成したくない場合は、コマンドラインから実際の単一のコード行を呼び出すことができます(読みやすくするために改行のみを使用)Rscript

$ Rscript -e 'd<-scan("stdin", quiet=TRUE)' \
          -e 'cat(min(d), max(d), median(d), mean(d), sep="\n")' < datafile
1
4
2
2.333333

美しいRマニュアルをお読みください:http://cran.r-project.org/manuals.html

残念ながら、参考文献全体はPDFとしてのみ提供されています。参照を読むもう1つの方法は、?topicname対話型Rセッションでプロンプトを入力することです。


完全性を期すために必要なすべての値とそれ以上を出力できるRコマンドがあります。残念ながら、人間に馴染みのある形式では、プログラム的に解析することは困難です。

> summary(c(1,2,4))
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  1.000   1.500   2.000   2.333   3.000   4.000 

答え3

私は実際には、数値データ(負数を含む)の単一列の合計、数、最小値、最大値、平均、および中央値を提供するawkプログラムを保持します。

#!/bin/sh
sort -n | awk '
  BEGIN {
    c = 0;
    sum = 0;
  }
  $1 ~ /^(\-)?[0-9]*(\.[0-9]*)?$/ {
    a[c++] = $1;
    sum += $1;
  }
  END {
    ave = sum / c;
    if( (c % 2) == 1 ) {
      median = a[ int(c/2) ];
    } else {
      median = ( a[c/2] + a[c/2-1] ) / 2;
    }
    OFS="\t";
    print sum, c, ave, median, a[0], a[c-1];
  }
'

上記のスクリプトは標準入力から読み込み、タブ区切りの出力列を1行に印刷します。

答え4

awkを使用すると、最小値、最大値、平均値を簡単に取得できます。

% echo -e '6\n2\n4\n3\n1' | awk 'NR == 1 { max=$1; min=$1; sum=0 }
   { if ($1>max) max=$1; if ($1<min) min=$1; sum+=$1;}
   END {printf "Min: %d\tMax: %d\tAverage: %f\n", min, max, sum/NR}'
Min: 1  Max: 6  Average: 3,200000

中央値を計算するのは少し面倒です。数字を並べ替えて、しばらくの間メモリに保存するか、2回読み込む必要があるためです(最初は計算し、2番目は中央値を求めます)。以下は、すべての数値をメモリに保存する例です。

% echo -e '6\n2\n4\n3\n1' | sort -n | awk '{arr[NR]=$1}
   END { if (NR%2==1) print arr[(NR+1)/2]; else print (arr[NR/2]+arr[NR/2+1])/2}' 
3

関連情報