0

私は perl が初めてで、ハッシュの使用に関して質問があります。同様の質問が投稿される前に投稿されましたが、私の問題に関連するものはありませんでした。

長さが異なるいくつかのシーケンスを含む fasta ファイルがあり、すべてのシーケンスの長さが同じになるまで、各 fasta エントリの末尾に文字列 (この場合は N) を追加したいと考えています。この時点で、fasta ファイルを読み取って、各シーケンスを文字列として (ただし、配列としても実行できます)、ハッシュの値に返すことができます。重要な要素は、fasta ファイルの対応するヘッダーです。

私のコードは次のとおりです。

###### calculate the length of each hash value and store the highest value in $max
my $length;
my $max = 0;
my $addN = "N";

foreach $name ( keys %seq ) {
    $length = length($seq{$name});
    if ($max < $length) {
        $max = $length;
    } else { next }
    print $max,"\n";

    while (length ($seq{$name}) < $max) {
        $seq{$name} .= $addN;
    }
    foreach $name (keys %seq) {
        print $seq{$name};
        print "\n";
    }
}

ここでの問題は、このコードの出力が入力とまったく同じであることです。たとえば、

INPUT:
>fasta1
AAAAAAAAA
>fasta2
AA
OUTPUT
>fasta1
AAAAAAAAA
>fasta2
AA

次のような出力が必要な場所:

>fasta1
AAAAAAAAA
>fasta2
AANNNNNNN

このタスクを達成するのを手伝ってくれませんか?

4

2 に答える 2

2
use 5.014;
my %seq = ( fasta1 => 'AAA',
            fasta2 => 'AAAAAA',
            fasta3 => 'AAAAAAAAA',
          );

my $length = length((sort { length($a) < length($b) } values %seq)[0]);
for my $name ( keys %seq ) {
    $seq{$name} = $seq{$name} . ('N' x ($length - length($seq{$name})));
}

while (my($name, $val) = each %seq ) {
    say "$name: $val";
}

fasta2: AAAAAANNN
fasta3: AAAAAAAAA
fasta1: AAANNNNNN
于 2012-10-11T17:40:59.303 に答える
1

サンプル コードが間違っています。ただし、「fasta」ファイルに基づいてマップを作成する方法があるようです。これが正しいと仮定すると、次のコードで問題が解決すると思います。

# Populate %seq from fasta file
%seq = (                                                         
    "fasta1"=> "AAAAAAAAA",                                      
    "fasta2" => "AAAA",                                          
    "fasta3" => "AA"                                             
);                                                               

my $FILL = "N";                                                  
my $normalized_length = 0;                                       

# If the normalized length = longest value                       
while( my ($k,$v) = each %seq) {                                 
    my $len = length($v);                                        
    $normalized_length = $len if $len > $normalized_length;      
}                                                                

while( my ($k,$v) = each %seq) {                                 
    print $v, $FILL x ($normalized_length - length($v)), "\n";   
} 

出力

AAAANNNNN
AANNNNNNN
AAAAAAAAA

固定長に正規化する必要がある場合は、$normalized_length をその値に設定し、最初の while ループをスキップします。

于 2012-10-11T17:57:47.837 に答える