2016-06-23 8 views
0

ich gruppieren möchten einige Daten auf der Basis der SubjectID SpaltePerl Daten in den Spalten Gruppierung nach dem SubjectID

Hier sind meine Daten

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 

ich gruppieren möchten die Ergebnisse nach dem SubjectID und die minimalen und maximalen Werte erhalten. Diese

ist, was das Ergebnis sollte wie folgt aussehen:

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 

Ich habe versucht, dies zu tun, indem Sie versuchen zwei Hashes von Arrays zu machen, damit die SubjectID der Schlüssel sein würde und die Ergebnisse würden der Wert sein. Aber ich kann nicht herausfinden, wie man die Ergebnisse nach SubjectID gruppiert.

+0

Ihre Daten sehen aus, als ob sie aus einer Datenbank stammen. Wenn dies der Fall ist, empfiehlt es sich, die Datenbank-Engine dazu zu bringen, die Berechnungen für Sie durchzuführen. Woher erhält Ihr Programm seine Daten? – Borodin

Antwort

1

Dies ergibt die erwartete Ausgabe:

#!/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); 
} 

Es verwendet nur eine Hash-Tabelle, die SubjectID der oberste Schlüssel zu sein. Die inneren Hashes haben die r1/r2 als Schlüssel, und die innersten Hashes haben max und min als Schlüssel. Die boolesche Variable $is_new wird verwendet, um die Ergebnisse für eine noch nicht verarbeitete ID zu initialisieren.

+0

Das ist sehr * Choroba *! – Borodin

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}; 
} 

Der Befund von min/max und Ausgang könnte für kürzeren Code kombiniert werden, aber dies sollte demonstrieren genug sein.

Verwandte Themen