通过添加这些值来根据第一列中的通用 id 合并行?

通过添加这些值来根据第一列中的通用 id 合并行?

我有一个制表符分隔的文件:

    Class      Sample_1     Sample_2      Sample_3
    A          0            0             0
    Z          0.25         0             0.75
    A|B|C      0            0             0
    A|B|C      0            1             0
    A|B|C      0.1875       0.671875      0.140625
    A|B|C      0.2739726027 0.5890410959  0.1369863014
    A|B|C|D|E  0            0.2           0.8
    A|B|C|D    0.1666666667 0.3333333333  0.5
    A|B|C|D    0.4723756906 0.179558011   0.3480662983

我想根据第一列中的 id 合并行并在合并时添加值:

Class       Sample_1        Sample_2        Sample_3
A           0               0               0
Z           0.25            0               0.75
A|B|C       0.4614726027    2.2609160959    0.2776113014
A|B|C|D|E   0               0.2             0.8
A|B|C|D     0.6390423573    0.5128913443    0.8480662983

答案1

这就是 GNU datamash 擅长的事情:

$ datamash -H groupby 1 sum 2-4 < file.tsv | column -t
GroupBy(Class)  sum(Sample_1)  sum(Sample_2)  sum(Sample_3)
A               0              0              0
Z               0.25           0              0.75
A|B|C           0.4614726027   2.2609160959   0.2776113014
A|B|C|D|E       0              0.2            0.8
A|B|C|D         0.6390423573   0.5128913443   0.8480662983

或者,在 GNU awk 中使用 2D 数组(尽管请注意,不能保证数组遍历的顺序 - 因此输出行不一定与输入的顺序相同):

$ gawk '
    BEGIN{getline; print} 
    {for(i=2;i<=4;i++) a[$1][i] += $i} 
    END {
      for(k in a){printf k; for(i=2;i<=4;i++) printf "\t%s", a[k][i]; printf "\n"}
    }' file.tsv | column -t
Class      Sample_1  Sample_2  Sample_3
A          0         0         0
A|B|C      0.461473  2.26092   0.277611
A|B|C|D    0.639042  0.512891  0.848066
A|B|C|D|E  0         0.2       0.8
Z          0.25      0         0.75

注意:我添加管道column -t只是为了视觉格式化

答案2

通过下面的方法完成

for i in `awk 'NR>1{if (!seen[$1]++){print $1}}' p.txt`; do awk -v i="$i" '$1 == i{print $0}' p.txt| awk -v i="$i" 'BEGIN{sum=0;hum=0;rum=0}{sum=sum+$2;hum=hum+$3;rum=rum+$4}END {print i,sum,hum,rum}'|awk '{printf "%s%14s%20s%20s\n",$1,$2,$3,$4}'; done| sed '1i  Class      Sample_1           Sample_2       Sample_3'

输出

Class      Sample_1           Sample_2       Sample_3
A             0                   0                   0
Z          0.25                   0                0.75
A|B|C      0.461473             2.26092            0.277611
A|B|C|D|E             0                 0.2                 0.8
A|B|C|D      0.639042            0.512891            0.848066

相关内容