我有以下代码。它工作正常,但输出与输入文件的顺序不同。例如我在输入的FASTA文件中有一个蛋白质列表。我的输出文件运行我的代码很好,但蛋白质的顺序似乎是随机的。
我错过了什么?
#!/usr/bin/perl
#usage: perl seqComp.pl <input_fasta_file> > <output_file>
use strict;
open( S, "$ARGV[0]" ) || die "cannot open FASTA file to read: $!";
my %s; # a hash of arrays, to hold each line of sequence
my %seq; #a hash to hold the AA sequences.
my $key;
while (<S>) { #Read the FASTA file.
chomp;
if (/>/) {
s/>//;
$key = $_;
} else {
push( @{ $s{$key} }, $_ );
}
}
foreach my $a ( keys %s ) {
my $s = join( "", @{ $s{$a} } );
$seq{$a} = $s;
#print("$a\t$s\n");
}
my @aa = qw(A R N D C Q E G H I L K M F P S T W Y V);
my $aa = join( "\t", @aa );
#print ("Sequence\t$aa\n");
foreach my $k ( keys %seq ) {
my %count; # a hash to hold the count for each amino acid in the protein
my @seq = split( //, $seq{$k} );
foreach my $r (@seq) {
$count{$r}++;
}
my @row;
push( @row, ">" . $k );
foreach my $a (@aa) {
$count{$a} ||= 0;
my $percentAA = sprintf( "%0.2f", $count{$a} / length( $seq{$k} ) );
push( @row,
$a . ":" . $count{$a} . "/" . length( $seq{$k} ) . "=" . sprintf( "%0.0f", $percentAA * 100 ) . "%" );
$count{$a} = sprintf( "%0.2f", $count{$a} / length( $seq{$k} ) );
# push(@row,$count{$a});
}
my $row = join( "\t\n", @row );
print("$row\n\n");
}
答案 0 :(得分:0)
hash
之类的%seq
没有特定的订单。
答案 1 :(得分:0)
数组保持顺序,哈希是随机顺序。如果要保留顺序,可以将键推送到数组中,但只有在哈希中不存在键或者重复时才执行此操作。
for(<S>) {
my ($key,$value) = &parse($_);
push @keys, $key unless exists $hash{$key};
$hash{$key} = $value;
}
for my $key (@keys) {
my $value = $hash{$key};
...
}
答案 2 :(得分:0)
如果订单很重要,请不要使用哈希。
相反,我建议使用如下数组的数组:
#!/usr/bin/perl
#usage: perl seqComp.pl <input_fasta_file> > <output_file>
use strict;
use warnings;
use autodie;
my $file = shift or die "Usage: perl $0 <input_fasta_file> > <output_file>";
open my $fh, '<', $file;
my @fasta;
while (<$fh>) { #Read the FASTA file.
chomp;
if (/>/) {
push @fasta, [ $_, '' ];
} else {
$fasta[-1][1] .= $_;
}
}
my @aa = qw(A R N D C Q E G H I L K M F P S T W Y V);
for (@fasta) {
my ( $k, $seq ) = @$_;
print "$k\n";
my %count; # a hash to hold the count for each amino acid in the protein
$count{$_}++ for split '', $seq;
for my $a (@aa) {
$count{$a} ||= 0;
printf "%s:%s/%s=%.0f%%\n", $a, $count{$a}, length($seq), 100 * $count{$a} / length($seq);
}
print "\n";
}