-4

参照ファイル

chr1    288598  288656

chr1    779518  779576

chr2    2569592 2569660

chr3    5018399 5018464

chr4    5182842 5182882

ファイル1

chr1    288598  288656 12

chr1    779518  779576 14

chr2    2569592 2569660 26

chr3    5018399 5018464 27

chr4    5182842 5182882 37

ファイル2

chr1    288598  288656 35

chr2    2569592 2569660 348

chr3    5018399 5018464 4326

chr4    5182842 5182882 68

参照ファイルを除いて、6 つの同様のファイルがあります。

ここで、最初の 3 つのフィールドは参照ファイルに似ています。したがって、6 つのファイルすべてから 4 番目の列のみをエクスポートし、参照ファイルに入れて新しい出力を作成したいと思います。これは、参照ファイルと同等である必要があります。一致しないところはゼロにします。

希望の出力

chr1    288598  288656 23 35 57 68 769 68

chr1    779518  779576 23 0 57 68 768 0

chr2    2569592 2569660 23 35 0 68 79 0

chr3    5018399 5018464 0 36 0 68 769 0

chr4    5182842 5182882 23 0 0 0 0 0

注:参照ファイルの長さは約 2000 で、他のファイルは常に同じ長さではありません (約 500、400、200、100 など)。そのため、ゼロを追加する必要があります。

この質問から答えを試しました

paste ref.file file1 file2 file3 file4 file5 file6 |  awk '{OFS="\t";print $1,$2,$3,$7,$11,$15,$19,$23,$27}' > final.common.out

しかし、機能していないようです — 一部の値が見落とされています。そして、一致しないところにゼロを追加する方法がわかりません。

4

1 に答える 1

2

このようなものはあなたが望むことをするべきだと思います。ハッシュを使用して「参照」ファイルを収集し、それを空の配列を持つキーのセットに変換します。

次に、他のファイルを反復処理し、「3 つの値」をキーとして抽出し、最後の値を実際の値として抽出します。

そして、2 つを比較し、「参照」ハッシュを値またはゼロで更新します。ここでの注意点 -参照ファイル (または重複) にない行はすべて消えてしまいます。

#!/usr/bin/perl

use strict;
use warnings;
use autodie;


#read 'reference file' into a hash:
my %ref;
open( my $ref_fh, "<", "reference_file" );
while (<$ref_fh>) {
    my ( $first, $second, $third ) = split;

    #turn the first three fields into space delimited key.
    $ref{"$first $second $third"} = ();
}

#open each of the files.
my @files = qw ( file1 file2 file3 file4 file5 file6 );
foreach my $input (@files) {
    open( my $input_fh, "<", $input );
    my %current;
    while (<$input_fh>) {

        #line by line, extract 'first 3 fields' to use as a key.
        #then 'value' which we store.
        my ( $first, $second, $third, $value ) = split;
        $current{"$first $second $third"} = $value;
    }

    #refer to 'reference file' and insert matching value or zero into
    #the array.
    foreach my $key ( keys %ref ) {
        push( @{ $ref{$key} }, $current{$key} ? $current{$key} : 0 );
    }
}

foreach my $key ( keys %ref ) {
    print join( " ", $key, @{ $ref{$key} } );
}
于 2015-02-10T18:15:31.237 に答える