如何从制表符分隔的数据文件中平均列值,忽略标题行和左列?
Posted
技术标签:
【中文标题】如何从制表符分隔的数据文件中平均列值,忽略标题行和左列?【英文标题】:How do I average column values from a tab-separated data file, ignoring a header row and the left column? 【发布时间】:2012-03-29 11:17:06 【问题描述】:我的任务是从以下名为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
、@987654326 @),并将上述各列的平均值写入一个新文件。
我一直在尽力弄清楚如何不考虑第一行或第一列,但每次我尝试在命令行上执行时,我都会不断出现“显式包名称”错误.
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.
我了解这涉及@
和$
,但即使知道我无法更改错误。
这是我的代码,但我强调我是上周刚开始的初学者:
#!/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";
如果有任何见解,我将不胜感激,也非常感谢通过列出您在每个步骤中所做的事情来让我知道 - 如果合适的话。我想学习,如果我能够阅读某人的流程,这对我来说会更有意义。
【问题讨论】:
好的,我看到你已经牢记use warnings
和use strict
的诫命。这就是您的错误的来源。您将“平均”声明为数组引用(有点),然后将其用作数组。尝试其中一个或另一个(但不是两者): 1. 将行更改为 @average 或 2. 使用 $average->[i]
正确取消引用注意,这不会解决整个问题,但它会消除错误消息为您服务,让您专注于逻辑。
哦,我只需要取消引用它。这确实消除了最后两个错误,你是对的,它并没有解决整个问题,因为我现在想出了这个:Can't use string ("5") as an ARRAY ref while "strict refs"在第 23 行,以下是您需要更改的要点 为标题使用另一个变量
my $count = 0;
my @header = ();
my @average = ();
然后改变if语句里面的逻辑
if ( $count == 1 )
@header = @columns;
现在不要使用@average
作为限制,使用$i < scalar @columns
作为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";
还有其他方法可以编写此代码,但我认为最好只是更正您的代码,这样您就可以轻松理解您的代码有什么问题。希望对你有帮助
【讨论】:
我只是想非常感谢你。我真的。它工作得很好,我可以看到正确的平均值。 0 为第一列,其他的被视为'header'。 我现在创建了一个“outfile”操作,以便可以将结果打印到文本文件中。 .txt 文件已生成,但其中没有文本。首先,我从修改后的脚本中得到的输出带有以下语句:'code' Argument "" is not numeric in ddition (+) at line X,以上是关于如何从制表符分隔的数据文件中平均列值,忽略标题行和左列?的主要内容,如果未能解决你的问题,请参考以下文章