他のフィールドの変数に基づくフィールドの平均を求めます。

他のフィールドの変数に基づくフィールドの平均を求めます。

他のフィールドの変数に基づいてフィールドの平均を取得する方法はありますか?たとえば、次の入力の場合

a x 3
b y 4
a y 2
b x 5
b x 20

この出力が欲しい

a 2.5
b 9.67

列の値の平均を求めるawkスクリプトを見つけました。

awk '{ total += $3; count++ } END { print total/count }' file.txt

しかし、最初の列の各変数の平均を取得するには、forループをどのように追加する必要がありますか?

ファイルはタブで区切られます。

ありがとう

答え1

あなたはこれからそれほど遠くありません。次に、インデックス付き配列を試してみてください$1

awk '{ total[$1] += $3; count[$1]++ } END {for (t in total) print t, total[t]/count[t]}' file
a 2.5
b 9.66667

または、質問のように小数点以下の2桁までを希望する場合:

$ awk '{ total[$1] += $3; count[$1]++ } END {for (t in total) printf "%s %.2f\n", t, total[t]/count[t]}' file
a 2.50
b 9.67

答え2

GNUの使用datamash:

$ datamash -R2 -W -s -g 1 mean 3 <file
a       2.50
b       9.67

$ datamash -W -s -g 1 mean 3 <file
a       2.5
b       9.6666666666667
  • -R2小数点以下2桁まで丸め
  • -Wスペースおよび/またはタブをフィールド区切り文字として使用
  • -sグループ化前のソート
  • -g 1最初のフィールドのグループ
  • mean 3値の平均、3番目のフィールド

出力でタブ文字を空白文字に置き換えるには、-Wタブ文字が区切り文字として追加した内容を削除します。--output-delimiter=' '

答え3

ミラーこのような作業にも便利です。

$ mlr --nidx stats1 -a mean -f 3 -g 1 file.txt
a 2.500000
b 9.666667

または(動詞を含む最新バージョンformat-values

$ mlr --nidx stats1 -a mean -f 3 -g 1 then format-values -f '%.2f' file.txt
a 2.50
b 9.67

答え4

   #!/bin/bash
counta=`awk '$1 ~ /^a$/{print NR}' filename| awk 'END{print NR}'`
countb=`awk '$1 ~ /^b$/{print NR}' filename| awk 'END{print NR}'`

awk -v counta="$counta" '{if ($1 == "a"){sum=sum+$NF}}END{print "a" " " sum/counta}'  filename

awk -v countb="$countb" '{if ($1 == "b"){sum=sum+$NF}}END{print "b" " " sum/countb}'  filename

出力

a 2.5
b 9.66667

関連情報