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 回答