Perl根据SubjectID对列中的数据进行分组

时间:2016-06-23 22:05:35

标签: perl

我想根据SubjectID

对一些数据进行分组

这是我的数据

SubjectID      Result1          Result2 
1                1.2              3.5
1                1.4              3.4
2                2.3              0.23
3                3.4               2.3
3                4.5               3.4
3                2.3               3.2

我想根据SubjectID对结果进行分组,并获取最小值和最大值。

这就是结果应该是这样的:

SubjectID     Result1Min      Result1Max        Result2Min        Result2Max
1                 1.2            1.4                3.4              3.5
2                 2.3            2.3                0.23             0.23
3                 2.3            4.5                2.3              3.4

我尝试通过尝试制作两个数组哈希来做到这一点,因此SubjectID将是关键,结果将是值。但我无法弄清楚如何根据SubjectID对结果进行分组。

2 个答案:

答案 0 :(得分:1)

这给出了预期的输出:

#!/usr/bin/perl
use warnings;
use strict;
use feature qw{ say };

<>; # Skip the header.
my %h;
while (<>) {
    my ($id, $r1, $r2) = split;
    my $is_new = ! exists $h{$id};
    $h{$id}{r1}{max} = $r1 if $is_new || $r1 > $h{$id}{r1}{max};
    $h{$id}{r1}{min} = $r1 if $is_new || $r1 < $h{$id}{r1}{min};
    $h{$id}{r2}{max} = $r2 if $is_new || $r2 > $h{$id}{r2}{max};
    $h{$id}{r2}{min} = $r2 if $is_new || $r2 < $h{$id}{r2}{min};
}

for my $id (sort { $a <=> $b } keys %h) {
    say join "\t", $id, map @{ $h{$id}{$_} }{qw{ min max }}, qw( r1 r2 );
}

它只使用一个哈希表,SubjectID是最顶层的键。内部哈希值以r1 / r2为键,最里面的哈希值为maxmin作为键。 $is_new布尔变量用于初始化尚未处理的id的结果。

答案 1 :(得分:0)

CodePad

use strict;
use warnings;
use List::Util qw(min max);

# Set Data
my $data = {
   1 => {
      Result1 => { data=> [1.2, 1.4] },
      Result2 => { data=> [3.5, 3.4] }
   },
   2 => {
      Result1 => { data => [2.3] },
      Result2 => { data => [.23] }
   },
   3 => {
      Result1 => { data => [3.4, 4.5, 2.3] },
      Result2 => { data => [2.3, 3.4, 3.2] }
   }
};

# Find Min/Max
foreach my $subjectId (sort keys %$data ){
   foreach my $result ( sort keys %{$data->{$subjectId}} ){
      my $obj = $data->{$subjectId}{$result};
      $obj->{min} = min @{$obj->{data}};
      $obj->{max} = max @{$obj->{data}};
   }
}

# Output
print qq{SubjectID\tResult1Min\tResult1Max\tResult2Min\tResult2Max\n};
foreach my $subjectId (sort keys %$data ){
   print qq{$subjectId\t\t};
   foreach my $result ( sort keys %{$data->{$subjectId}} ){
      my $obj = $data->{$subjectId}{$result};
      print qq{$obj->{min}\t\t$obj->{max}\t\t};
   }
   print qq{\n};
}

最小/最大和输出的结果可以合并为更短的代码,但这应该足以证明。