Perl格式化csv文件并计算出现次数并放入行中

Perl to format csv file and count occurances and put into rows

我正在尝试编写一个接受 csv 例如的 perl 脚本。

得分,编号
1,6833
0.508201,2759
0.587154,2759
0.845473,2759
0.882188,33630

并输出例如。

id,score,abundance
6833,1,1
2759,0.508201,0.845473,1,3
33630,0.882188,1

只取第 1 列 >=0.5 的行。然后像 2759 一样重复的第 2 列,收集它后面的分数。最后一个数字是例如 2759 的丰度,它出现了 3 次。

#!/usr/bin/perl
use strict;
use warnings;
open( my $csv, "$ARGV[0]" ) or die "Failed to open file: $!\n";
open( my $csv_spp, ">$ARGV[0]_spp_ML.csv" );

while ( my $line = <$csv> ) {
    my ( $ml, $id ) = split( /,/, $line );
    if ( $ml >= 0.5 ) {

        if ( $id = $id ) {
            my $count++;
        }

        print $csv_spp $id, $count;
    }
}
close($csv);
close($csv_spp);

我被困在如何让数字跟随或计数出现。

您的问题在这里:

if ( $id = $id ) {
    my $count++;
}

这……是胡说八道。 $count 是词法范围的,所以在你 'increment' 它之后,它然后......超出范围并再次消失。

此外,测试是否 $id = $id - 即使你的意思是 == 你正在测试某物是否等于它自己。 (如果你不这样做,你就是在测试你是否可以给自己分配一些东西,这就没有意义了)。

您的意思可能是使用散列来计算您的出现次数,并且您可能需要另一个数组散列来整理您的值。

像这样:

#!/usr/bin/perl
use strict;
use warnings;
open( my $csv, '<', "$ARGV[0]" ) or die "Failed to open file: $!\n";
open( my $csv_spp, '>', "$ARGV[0]_spp_ML.csv" );

my %count_of; 
my %values_of; 

while ( my $line = <$csv> ) {
    chomp; 
    my ( $ml, $id ) = split( /,/, $line );
    if ( $ml >= 0.5 ) {
        $count_of{$id}++; 
        push ( @{$values_of{$id}}, $id );
    }
}
close($csv);

foreach my $id ( sort keys %count_of ) {
   print {$csv_spp} join ( ",", $id, @{$values_of{$id}}, $count_of{$id} ),"\n";
}

close($csv_spp);

您可能还想考虑使用 Text::CSV 来阅读您的文件。