共通値で行をマージする

共通値で行をマージする

グループ内のすべての一致が見つかるように、テキストファイル内の一致のペアを結合しようとしています。

私のファイルには、次の2つのタブで区切られた列が含まれています。

Simon John
Simon Paul
Steve Simon
Graham Dave
Dave Jason
Paul Simon
Peter Derek

出力グループを含むファイルが必要です。

Simon John Paul Steve
Graham Dave Jason
Peter Derek

どんな助けでもとても役に立ちます!以下のスクリプトを試しましたが、一致が重複しているように見えます(たとえば、Simonは出力ファイルの別の行に2回表示されます)、実行に時間がかかります。理想的には、bashでこれを行う方法があると思います。

use strict;

my(@homologs,$genefile,@temp,$line,$found,$i,$j);

$genefile="Arabidopsis_combined.txt";

open(IN,"<$genefile") or die "cannot open $genefile\n";
$j=0;
while(!eof(IN)){
    $line=readline *IN;
    chomp($line);
    @temp=split /\t/,$line;
    $i=0;
    $found="F";
    while($i<@homologs){
        if($temp[0]~~@{$homologs[$i]}){
            if($temp[1]~~@{$homologs[$i]}){}
            else{push @{$homologs[$i]},$temp[1];}
            $found="T"; 
            }
        if($temp[1]~~@{$homologs[$i]}){
            if($temp[0]~~@{$homologs[$i]}){}
            else{push @{$homologs[$i]},$temp[0];}
            $found="T";         
            }
        $i++;       
        }
    if($found eq "F"){
        push @homologs,[@temp];
        }
    print $j."\n";
    $j++;
    }
close(IN);

print "Number of groups of homologs: ".@homologs."\n";

open(OUT,">homologs.txt");
$i=0;
while($i<@homologs){
    print OUT "@{$homologs[$i]}"."\n";
    $i++;   
    }
close(OUT);

答え1

これは、無向グラフでリンクされたコンポーネントを見つける標準的な問題です。あなたの質問に次のタグを付けましたperl

#!/usr/bin/env perl

use v5.10;                                       
use strict;
use warnings;

use Graph::Undirected;

my $g = Graph::Undirected->new;

while (<>) {
    chomp;
    $g->add_edge( split /\t/ );
}

for ( $g->connected_components() ) {
    say join ' ', @$_;
}

またはそれに対応するコマンドライン:

perl -MGraph::Undirected -F'\t' -lane '
  BEGIN{$g=Graph::Undirected->new}
  $g->add_edge(@F);
  END{$,=" ";print @$_ for $g->connected_components}'

関連情報