【问题标题】:how to merge rows that share unique IDs into a comma separated table如何将共享唯一 ID 的行合并到逗号分隔的表中
【发布时间】:2015-07-08 12:45:32
【问题描述】:

我想询问一些有关如何将共享唯一 ID 的行合并到逗号分隔表中的提示。非常感谢 Perl、sed 或 awk 中的任何提示。

这就是我现在的表格的样子:

protein_id go_id
4102    GO:0003676
4125    GO:0003676
4125    GO:0008270
4139    GO:0008270

这就是我想要转换的方式:

protein_id  go_id
4102    GO:0003676
4125    GO:0003676, GO:0008270
4139    GO:0008270

【问题讨论】:

  • bash merge multiple lines 的可能重复项
  • 你可以试试:awk 'NR==0{print $0} NR!=1{a[$1]=a[$1] FS $2}END{for(i in a) print i,a[i]}' filename
  • 在 perl 中最简单的方法是解析成以键为第一列的数组散列,然后根据需要打印散列。
  • 非常感谢 Rakholiya Jenish,awk 工作得很好!
  • 感谢 stevesliva 的 perl 提示,我将尝试用 hash 编写它,以便将来修改!

标签: perl awk sed


【解决方案1】:

使用数组的 Perl 哈希...

#!/usr/bin/perl
use warnings;
use strict;

my %data;
my $header;

while(<DATA>){
    chomp;

    if ($. == 1){
        $header = $_;
        next;
    }
    push @{ $data{(split)[0]} }, (split)[1];
}

print "$header\n";

for my $k (sort {$a<=>$b} keys %data){

    print "$k\t";
    print join(', ', @{ $data{$k} });
    print "\n";
}

__DATA__
protein_id go_id
4102    GO:0003676
4125    GO:0003676
4125    GO:0008270
4139    GO:0008270

【讨论】:

    【解决方案2】:

    使用awk

    输入

    $ cat file
    protein_id go_id
    4102    GO:0003676
    4125    GO:0003676
    4125    GO:0008270
    4139    GO:0008270
    

    输出(如果顺序无关紧要)

    $ awk 'FNR==1{print;next}{A[$1]=$1 in A ? A[$1]", "$2:$2}END{for(i in A)print i,A[i]}' file
    protein_id go_id
    4139 GO:0008270
    4102 GO:0003676
    4125 GO:0003676, GO:0008270
    

    可读性更好的版本

    awk '
          FNR==1{
                  print
                  next
                }
                {
                  A[$1]=$1 in A ? A[$1]", "$2:$2
                }
             END{
                  for(i in A)
                       print i,A[i]
                }
        ' file
    

    输出(如果顺序很重要)

    $ awk 'FNR==1{print;next}$1 in A{A[$1]=A[$1]", "$2;next}{A[O[++c]=$1]=$2}END{for(i=1; i in O; i++)print O[i],A[O[i]]}' file
    protein_id go_id
    4102 GO:0003676
    4125 GO:0003676, GO:0008270
    4139 GO:0008270
    

    可读性更好的版本

    awk '
         FNR==1{
                 print
                 next
               }
        $1 in A{
                 A[$1]=A[$1]", "$2
                 next
               }
               {
                A[O[++c]=$1]=$2
               }
            END{
                 for(i=1; i in O; i++)
                      print O[i],A[O[i]]
               }
        ' file
    

    【讨论】:

      【解决方案3】:
      $ cat data.txt 
      protein_id go_id
      4102    GO:0003676
      4125    GO:0003676
      4125    GO:0008270
      4139    GO:0008270
      $ perl -aE'sub a{say"$a\t",join", ",@a if$a;@a=($F[1]);$a=$F[0]}$F[0]eq$a?push@a,$F[1]:a()}{a()' data.txt
      protein_id      go_id
      4102    GO:0003676
      4125    GO:0003676, GO:0008270
      4139    GO:0008270
      

      【讨论】:

        猜你喜欢
        • 2023-03-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多