3

我的任务是从以下数据文件中计算平均值,标题为Lab1_table.txt

retrovirus      genome  gag     pol     env
HIV-1           9181    1503    3006    2571
FIV             9474    1353    2993    2571
KoRV            8431    1566    3384    1980
GaLV            8088    1563    3498    2058
PERV            8072    1560    3621    1532

我必须编写一个脚本来打开并读取这个文件,通过将内容拆分为一个数组来读取每一行,然后计算数值的平均值(genome, gag, pol, env),然后将每个文件的平均值写入一个新文件上述列。

我一直在尽力弄清楚如何不考虑第一行或第一列,但是每次我尝试在命令行上执行时,我都会不断出现“显式包名称”错误。

Global symbol @average requires explicit package name at line 23.
Global symbol @average requires explicit package name at line 29.
Execution aborted due to compilation errors.

我知道这涉及@and $,但即使知道我无法更改错误。

这是我的代码,但我强调我是上周刚开始的初学者:

#!/usr/bin/perl -w
use strict;

my $infile = "Lab1_table.txt"; # This is the file path
open INFILE, $infile or die "Can't open $infile: $!";

my $count = 0;
my $average = ();

while (<INFILE>) {
    chomp;
    my @columns = split /\t/;
    $count++;
    if ( $count == 1 ) {
        $average = @columns;
    }
    else {
        for( my $i = 1; $i < scalar $average; $i++ )  {
            $average[$i] += $columns[$i];
        }
    }
}

for( my $i = 1; $i < scalar $average; $i++ ) {
    print $average[$i]/$count, "\n";
}

如果有任何见解,我将不胜感激,我也非常感谢通过列出您在每个步骤中所做的事情来让我知道 - 如果合适的话。我想学习,如果我能够阅读某人的流程,这对我来说会更有意义。

4

1 回答 1

2

以下是您需要更改的要点
为标题使用另一个变量

my $count = 0;
my @header = ();
my @average = ();

然后更改 if 语句中的逻辑

if ( $count == 1 ) {
    @header = @columns;
}

现在不要使用@averagefor 限制,使用$i < scalar @columnsfor else 语句。最初@average为零,你永远不会进入 for 循环。

else {
    for( my $i = 1; $i < scalar @columns; $i++ )  {
        $average[$i] += $columns[$i];
    }
}

最后添加-1到您的柜台。请记住,在解析标题时增加计数器

for( my $i = 1; $i < scalar @average; $i++ ) {
    print $average[$i]/($count-1), "\n";
}

这是最终代码
您可以利用@header它来整齐地显示结果

#!/usr/bin/perl -w

use strict;

my $infile = "Lab1_table.txt"; # This is the file path
open INFILE, $infile or die "Can't open $infile: $!"; 

my $count = 0;
my @header = ();
my @average = ();

while (<INFILE>) {
    chomp;


    my @columns = split /\t/;
    $count++;
    if ( $count == 1 ) {
        @header = @columns;
    }
    else {
        for( my $i = 1; $i < scalar @columns; $i++ )  {
            $average[$i] += $columns[$i];
        }
    }
} 

for( my $i = 1; $i < scalar @average; $i++ ) {
    print $average[$i]/($count-1), "\n";
}

还有其他方法可以编写此代码,但我认为最好只是更正您的代码,以便您可以轻松理解代码的问题所在。希望能帮助到你

于 2012-03-13T03:15:52.323 回答