一部のデータを各列の合計のパーセンテージに変換しようとしています。各列に対してこれを行う必要があることを除いて、このスレッドと非常によく似ています。 AWKを使用した合計の計算と除算
データは次のようになります(ただし、より多くの列と行)。
ID Sample1 Sample2 Sample3
One 10 0 5
Two 3 6 8
Three 3 4 7
希望の出力は次のとおりです。
ID Sample1 Sample2 Sample3
One 62.50 0.0 25.0
Two 18.75 60.0 40.0
Three 18.75 40.0 35.0
以下は単一の列に対して機能しますが、最初の列を除くすべての列に対してこれを行いたいと思います。
gawk -F"\t" '{a[NR]=$1;x+=(b[NR]=$2)}END{while(++i<=NR)print a[i]"\t"100*b[i]/x}' file.txt
あなたが提供できる助けに心から感謝します。
ベストアンサー1
出力は要求されたものと100%同じではありませんが、十分に似ていると予想されます。
function percent(value, total) {
return sprintf("%.2f", 100 * value / total);
}
{
label[NR] = $1
for (i = 2; i <= NF; ++i) {
sum[i] += col[i][NR] = $i
}
}
END {
title = label[1]
for (i = 2; i <= length(col) + 1; ++i) {
title = title "\t" col[i][1];
}
print title
for (j = 2; j <= NR; ++j) {
line = label[j]
for (i = 2; i <= length(col) + 1; ++i) {
line = line "\t" percent(col[i][j], sum[i]);
}
print line
}
}
出力を生成します。
ID Sample1 Sample2 Sample3 One 62.50 0.00 25.00 Two 18.75 60.00 40.00 Three 18.75 40.00 35.00
実行するgawk -f script.awk file.txt
もちろんです。できるスクリプトを1行に簡素化しますが、読みやすくするためにこのようなスクリプトファイルに保存する方が良いと思います。
GNU AWKだけでなくBSD AWKでも動作する、よりシンプルでより良いバージョン:
function percent(value, total) {
return sprintf("%.2f", 100 * value / total)
}
BEGIN { OFS = "\t" }
NR == 1 { gsub(/ +/, OFS); print; next }
{
label[NR] = $1
for (i = 2; i <= NF; ++i) {
sum[i] += col[i, NR] = $i
}
}
END {
for (j = 2; j <= NR; ++j) {
$1 = label[j]
for (i = 2; i <= NF; ++i) {
$i = percent(col[i, j], sum[i])
}
print
}
}