我有一个for循环,其中嵌套有if,else和elsif语句。 for循环可以正确运行,但是由于某种原因它只能运行一次。我想按顺序计算A,C,G和T,但是我想将它们分为两组-主题组和背景组。主题组计数需要特定于位置,而背景计数则不需要。
这是我的.dna文件中包含的内容(.txt可以正常工作): AGGCT
这是我到目前为止所拥有的:
use strict;
use warnings;
#Upload sequence
print "Please enter the filename of the first sequence data: ";
my $filename1 = <STDIN>;
#Remove newline from file
chomp $filename1;
#Open the file and ignore comment lines
open (FILE, '<', $filename1) or die "Cannot open $filename1.",$!;
my $dna;
for (<FILE>)
{
next if /^#/;
next if /^>/;
$dna .= $_;
}
close FILE;
#Remove white spaces
$dna =~ s/[\s\d]//g;
$dna =~ /./g;
#User specifies motif width
print "Please enter the motif width:\n";
my $width = <STDIN>;
#Remove newline from file
chomp $width;
#Omitting code for non-negative widths to keep this shorter
#Initialize counts and arrays for motif positions
my @motA;
my @motC;
my @motG;
my @motT;
#Define length of motif arrays per width
for(0..($width-1))
{
$motA[$_] = 0;
$motC[$_] = 0;
$motG[$_] = 0;
$motT[$_] = 0;
}
#Initialize background counts
my $bgA = 0;
my $bgC = 0;
my $bgG = 0;
my $bgT = 0;
#Generate random start site in the sequence
#for motif to start from
my $ms = int(rand(((length($dna)+1)-$width)));
#Within a motif, count the bases at the positions
for (my $pos = 0..(length($dna)-1))
{
my $base = substr($dna, $pos, 1);
if ($pos = $ms..($ms + $width))
{
#Add to motif counts
if($base eq 'A')
{
$motA[$pos-$ms] = $motA[$pos-$ms] + 1;
}
elsif($base eq 'C')
{
$motC[$pos-$ms] = $motC[$pos-$ms] + 1;
}
elsif($base eq 'G')
{
$motG[$pos-$ms] = $motG[$pos-$ms] + 1;
}
elsif($base eq 'T')
{
$motT[$pos-$ms] = $motT[$pos-$ms] + 1;
}
}
else
{
#Create background counts
if ($base eq 'A')
{
$bgA = $bgA + 1;
}
elsif ($base eq 'C')
{
$bgC = $bgC + 1;
}
elsif ($base eq 'G')
{
$bgG = $bgG + 1;
}
elsif ($base eq 'T')
{
$bgT = $bgT + 1;
}
}
}
print "A @motA\nC @motC\nG @motG\nT @motT\n\n";
print "bgA = $bgA\n
bgC = $bgC\n
bgG = $bgG\n
bgT = $bgT";
输出看起来像这样:
Please enter the filename of the first sequence data: sample.dna
Please enter the motif width:
3
Argument "" isn't numeric in substr at line 62, <STDIN> line2.
A 0 1 0
C 0 0 0
G 0 0 0
T 0 0 0
bgA = 0
bgC = 0
bgG = 0
bgT = 0
我知道这很可能是因为我的$ dna或$ pos的substr行中包含“”(空字符串?),但是我不确定如何解决此问题。我以为$ pos的初始化可以解决这个问题,所以这就是为什么我想请高手看看该怎么做。我认为这也将解决for循环问题。与往常一样,任何帮助都是有用的。我预先感谢!
答案 0 :(得分:3)
此:
for (my $pos = 0..length($dna))
{
my $base = substr($dna, $pos, 1);
大概应该是0..length($dna)-1
吗?
当$ pos为长度时,子字符串将为空字符串。
那不是for循环遍历一个范围的正确语法。应该是
for my $pos (0..length($dna)-1)
此:
if ($pos = $ms..($ms + $width))
如果我正确理解应该是
if ($pos >= $ms && $pos < $ms + $width)
您拥有的是将触发器操作的结果分配给$ pos,
它看起来像这样:
my $ms = int(rand(((length($dna)+1)-$width)));
应该是
my $ms = int(rand(((length($dna))-$width)));
例如如果$ dna的长度为10,宽度为3,则您希望起始偏移量为0到7,而不是0到8。
看起来您在主题中的计数应该使用主题中的位置,而不是$ pos;这个:
$motA[$pos] = $motA[$pos] + 1;
应该是
$motA[$pos-$ms] = $motA[$pos-$ms] + 1;