【发布时间】:2017-03-30 04:01:11
【问题描述】:
我正在使用 Perl 编写一个程序,但我的输出是错误的,并且需要很长时间才能处理。该代码旨在接收一个大型 DNA 序列文件,以 15 个字母增量 (kmers) 读取它,一次向前走 1 个位置。我应该将 kmer 序列输入到哈希中,它们的值是该 kmer 的出现次数——这意味着每个键应该是唯一的,当找到重复项时,它应该增加该特定 kmer 的计数。我从我的教授预期的输出文件中知道,我有太多的行,所以它允许重复并且不正确计数。它也运行了 5 分钟以上,所以我必须 Ctrl+C 才能逃脱。当我查看 kmers.txt 时,该文件至少已正确写入和格式化。
#!/usr/bin/perl
use strict;
use warnings;
use diagnostics;
# countKmers.pl
# Open file /scratch/Drosophila/dmel-2L-chromosome-r5.54.fasta
# Identify all k-mers of length 15, load them into a hash
# and count the number of occurences of each k-mer. Each
# unique k-mer and its' count will be written to file
# kmers.txt
#Create an empty hash
my %kMersHash = ();
#Open a filehandle for the output file kmers.txt
unless ( open ( KMERS, ">", "kmers.txt" ) ) {
die $!;
}
#Call subroutine to load Fly Chromosome 2L
my $sequenceRef = loadSequence("/scratch/Drosophila/dmel-2L-chromosome-r5.54.fasta");
my $kMer = 15; #Set the size of the sliding window
my $stepSize = 1; #Set the step size
for (
#The sliding window's start position is 0
my $windowStart = 0;
#Prevent going past end of the file
$windowStart <= ( length($$sequenceRef) - $kMer );
#Advance the window by the step size
$windowStart += $stepSize
)
{
#Get the substring from $windowStart for length $kMer
my $kMerSeq = substr( $$sequenceRef, $windowStart, $kMer );
#Call the subroutine to iterate through the kMers
processKMers($kMerSeq);
}
sub processKMers {
my ($kMerSeq) = @_;
#Initialize $kCount with at least 1 occurrence
my $kCount = 1;
#If the key already exists, the count is
#increased and changed in the hash
if ( not exists $kMersHash{$kMerSeq} ) {
#The hash key=>value is loaded: kMer=>count
$kMersHash{$kMerSeq} = $kCount;
}
else {
#Increment the count
$kCount ++;
#The hash is updated
$kMersHash{$kMerSeq} = $kCount;
}
#Print out the hash to filehandle KMERS
for (keys %kMersHash) {
print KMERS $_, "\t", $kMersHash{$_}, "\n";
}
}
sub loadSequence {
#Get my sequence file name from the parameter array
my ($sequenceFile) = @_;
#Initialize my sequence to the empty string
my $sequence = "";
#Open the sequence file
unless ( open( FASTA, "<", $sequenceFile ) ) {
die $!;
}
#Loop through the file line-by-line
while (<FASTA>) {
#Assign the line, which is in the default
#variable to a named variable for readability.
my $line = $_;
#Chomp to get rid of end-of-line characters
chomp($line);
#Check to see if this is a FASTA header line
if ( $line !~ /^>/ ) {
#If it's not a header line append it
#to my sequence
$sequence .= $line;
}
}
#Return a reference to the sequence
return \$sequence;
}
【问题讨论】:
-
您正在处理/输出每一步。您可能想先完成这些步骤,然后输出您的哈希值。您只需执行
$kMersHash{$kMerSeq}++;即可简化计数,因为 perl 会自动激活(如果不存在则创建)您的哈希键。 -
我知道它必须是我的 processKMers 子例程中的某些内容重复且效率低下,我只是不知道是什么。
-
这是因为您每次调用
processKMers时都在printing 密钥,这是针对每一步的。将打印逻辑移出子程序,在处理完整个字符串后只执行一次。 -
@xxfelixxx 所以你是说我可以完全取出我的 if else 并增加?
-
是的。这是一篇关于它的好文章:effectiveperlprogramming.com/2011/04/…
标签: perl hash bioinformatics