perl 求和 csv 文件中的所有值,然后将每个值除以它
perl to sum all values in csv file then divide each value by it
我有 csv 文件,示例如下
1003036,0.0198942841
1003075,0.0132738331
1003144,0.0530953324
1003149,0.0231666023
1003199,0.0132738331
1003208,0.0115833012
第一列是 ID,第二列是我要计算的 ID。我想总结第二列,因为在这个例子中它将是 0.1342871862,然后将这些数字中的每一个除以它。
例如
0.0198942841/0.1342871862
然后乘以 1000000。每个都这样。
我下面有一个脚本
#!/usr/bin/perl
use strict;
use warnings;
open taxa_fh, '<', "$ARGV[0]"
or die qq{Failed to open "$ARGV[0]" for input: $!\n};
open match_fh, ">$ARGV[0]_NORM_FILES.csv"
or die qq{Failed to open for output: $!\n};
my ( $tax_id, $abundance );
my $Total;
my $sum2;
while ( my $line = <taxa_fh> ) {
chomp($line);
( $tax_id, $abundance ) = split( /,/, $line );
$Total += $abundance;
foreach (<>) {
$sum2 = ( ( $abundance / $Total ) * 1000000 );
}
}
print match_fh "$tax_id,$sum2\n";
close taxa_fh;
close match_fh;
问题是它只输出一个,而且总是最后一个值。
这里发生了一些非常令人困惑的事情 - 你从 ARGV
中读取了一些东西来打开你的文件,但是你也使用 foreach ( <> )
来打开并读取指定的文件@ARGV
这...几乎可以肯定不是您希望它做的事。
我建议您可能根本不希望 foreach
循环存在,因为它实际上 也 将打开与中指定的相同文件taxa_fh
(无法打开文件 match_fh
,因为没有名为该文件的文件)。
所以我认为你正在以一种奇怪的方式离题。
如果我没理解错的话,你想要的是:
#!/usr/bin/perl
use strict;
use warnings;
open my $taxa_fh, '<', "$ARGV[0]"
or die qq{Failed to open "$ARGV[0]" for input: $!\n};
open my $match_fh, ">$ARGV[0]_NORM_FILES.csv"
or die qq{Failed to open for output: $!\n};
my @data = map { [split /,/] } <$taxa_fh>;
my $sum = 0;
$sum += $_->[1] for @data;
foreach my $row ( @data ) {
$row -> [1] *= 1_000_000 / $sum;
print {$match_fh} join ( ",", @$row ),"\n";
}
根据您的输入生成:
1003036,148147.300296921
1003075,98846.6098338726
1003144,395386.43933549
1003149,172515.360218338
1003199,98846.6098338726
1003208,86257.6804815052
我有 csv 文件,示例如下
1003036,0.0198942841
1003075,0.0132738331
1003144,0.0530953324
1003149,0.0231666023
1003199,0.0132738331
1003208,0.0115833012
第一列是 ID,第二列是我要计算的 ID。我想总结第二列,因为在这个例子中它将是 0.1342871862,然后将这些数字中的每一个除以它。
例如
0.0198942841/0.1342871862
然后乘以 1000000。每个都这样。
我下面有一个脚本
#!/usr/bin/perl
use strict;
use warnings;
open taxa_fh, '<', "$ARGV[0]"
or die qq{Failed to open "$ARGV[0]" for input: $!\n};
open match_fh, ">$ARGV[0]_NORM_FILES.csv"
or die qq{Failed to open for output: $!\n};
my ( $tax_id, $abundance );
my $Total;
my $sum2;
while ( my $line = <taxa_fh> ) {
chomp($line);
( $tax_id, $abundance ) = split( /,/, $line );
$Total += $abundance;
foreach (<>) {
$sum2 = ( ( $abundance / $Total ) * 1000000 );
}
}
print match_fh "$tax_id,$sum2\n";
close taxa_fh;
close match_fh;
问题是它只输出一个,而且总是最后一个值。
这里发生了一些非常令人困惑的事情 - 你从 ARGV
中读取了一些东西来打开你的文件,但是你也使用 foreach ( <> )
来打开并读取指定的文件@ARGV
这...几乎可以肯定不是您希望它做的事。
我建议您可能根本不希望 foreach
循环存在,因为它实际上 也 将打开与中指定的相同文件taxa_fh
(无法打开文件 match_fh
,因为没有名为该文件的文件)。
所以我认为你正在以一种奇怪的方式离题。
如果我没理解错的话,你想要的是:
#!/usr/bin/perl
use strict;
use warnings;
open my $taxa_fh, '<', "$ARGV[0]"
or die qq{Failed to open "$ARGV[0]" for input: $!\n};
open my $match_fh, ">$ARGV[0]_NORM_FILES.csv"
or die qq{Failed to open for output: $!\n};
my @data = map { [split /,/] } <$taxa_fh>;
my $sum = 0;
$sum += $_->[1] for @data;
foreach my $row ( @data ) {
$row -> [1] *= 1_000_000 / $sum;
print {$match_fh} join ( ",", @$row ),"\n";
}
根据您的输入生成:
1003036,148147.300296921
1003075,98846.6098338726
1003144,395386.43933549
1003149,172515.360218338
1003199,98846.6098338726
1003208,86257.6804815052