【问题标题】:for loop only runs once PERL, Argument "" isn't numeric in substrfor 循环只运行一次 PERL,参数 "" 在 substr 中不是数字
【发布时间】:2019-03-16 16:11:17
【问题描述】:

我有一个 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

我知道这很可能是因为我在 substr 行中的 $dna 或 $pos 包含“”(空字符串?),但我不确定如何解决这个问题。我以为 $pos 的初始化会解决这个问题,但这就是为什么我想请大师们看看该怎么做。我认为这也将解决 for 循环问题。与往常一样,任何和所有帮助都是有用的。我提前感谢它!

【问题讨论】:

  • 无法想象if ($pos = $ms..($ms + $width)) 想要做什么。你能解释一下吗?
  • 我想将主题中的计数与背景分开。 $ms(motif start)到($ms+$width)是motif的位置。

标签: perl for-loop count substr


【解决方案1】:

这个:

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;

【讨论】:

  • 你是对的。不幸的是,当我纠正这个错误时,我仍然得到空字符串错误。
  • 添加回答
  • 这更有意义。我仍然收到警告(我想我不应该将其称为错误),并且循环仅在更改该部分后运行一次。
  • 增加了几个问题。
  • 除了@ysth 的修复之外,您应该使用散列而不是整串类似命名的变量,如here 所示。
猜你喜欢
  • 1970-01-01
  • 2021-06-15
  • 2014-12-07
  • 2023-03-24
  • 1970-01-01
  • 1970-01-01
  • 2022-10-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多