Calculating percentages in arbitrary number of columns Given this sample input:




ID     Sample1     Sample2      Sample3
One      10          0            5
Two      3           6            8
Three    3           4            7



I needed to produce this output using GNU AWK (awk in Linux, gawk in BSD):


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



This is how I solved it:



function percent(value, total) {
    return sprintf("%.2f", 100 * value / total)
}
{
    label[NR] = $1
    for (i = 2; i &lt;= NF; ++i) {
        sum[i] += col[i][NR] = $i
    }
}
END {
    title = label[1]
    for (i = 2; i &lt;= length(col) + 1; ++i) {
        title = title "\t" col[i][1]
    }
    print title
    for (j = 2; j &lt;= NR; ++j) {
        line = label[j]
        for (i = 2; i &lt;= length(col) + 1; ++i) {
            line = line "\t" percent(col[i][j], sum[i])
        }
        print line
    }
}


What do you think about this implementation? How would you improve it?
It's quite good. I can only slightly simplify it:

NR==1 {print; next} 
{
    label[NR] = $1
    for (i=2; i&lt;=NF; i++) { sum[i] += $i; val[NR,i] = $i }
}
END {
    OFS = "\t"
    for (nr=2; nr&lt;=NR; nr++) {
        $1 = label[nr]
        for (i=2; i&lt;=NF; i++) $i = sprintf("%.2f", 100*val[nr,i]/sum[i])
        print
    }
}



don't need to store the header line, just print it and move on
I find sum[i] += col[i][NR] = $i needlessly complicated
take advantage of OFS and awk can build the line itself