"Chris Stinemetz" wrote in message news
Hello List,
I have input data such as far below:
I would like to read the data into an array and modify the 2nd index if the
0th and first indices are identical.
I would like the updated 2nd index to be an average of the 2nd index where
both occurences of 0th and 1st indices match.
So for example below:
The records that contain 24 1 I would like to average the second index 60
and 40
and print the new value like this:
... # print input data
24 1 50 65
24 1 50 65
... # print rest of input data
22 1 60 65
22 2 180 90
22 3 300 90
23 1 0 65
23 2 90 65
23 3 260 65
24 1 60 65
24 1 40 65
24 2 180 65
24 2 160 65
24 3 310 65
24 3 290 65
. . . . .
Hi Chris,
I hope my identical post through Google groups doesn't find its way here. It
never made the list, so I'm re-posting from my email program. (Or, perhaps I
didn't trim enough in that post.)
There are many Perl idioms here, so if you don't understand parts, just ask.
It might be helpful to uncomment 'print Dumper \%data;' to visualize the
data structure I created.
I made a sub called 'sum', but if you have perl version 5.8 or higher, you
could use the sum function from List::Util. It is part of the perl
distribution and doesn't require installing the module from CPAN.
I read from the DATA filehandle, but am not including the data here as it is
the same as you provided in your question.
Chris
The program:
#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
$Data::Dumper::Sortkeys = 1;
my %data;
while (<DATA>) {
my ($col0, $col1, @rest) = split; # @rest is columns 2 and 3
push @{ $data{$col0, $col1} }, \@rest;
}
#print Dumper \%data;
for my $comp_key (sort composite keys %data) {
my $aref = $data{$comp_key}; # array_reference
my $avg = sprintf "%.f", sum( map $_->[0], @$aref ) / @$aref;
my ($col0, $col1) = split /$;/, $comp_key;
for my $i (0 .. $#$aref) {
print join(" ", $col0, $col1, $avg, $aref->[$i][1]), "\n";
}
}
sub composite {
my ($a_col0, $a_col1) = split /$;/, $a;
my ($b_col0, $b_col1) = split /$;/, $b;
$a_col0 <=> $b_col0 || $a_col1 <=> $b_col1;
}
sub sum {
my $sum;
$sum += $_ for @_;
return $sum;
}
__DATA__
22 1 60 65
22 2 180 90
22 3 300 90
23 1 0 65
. . . .
--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/