histogram and perl

A

Andrea Spitaleri

Hi folks,
I am stuck with a problem. Here it is:
I have got an @array1 and I would like to calculate the frequency of
its element by a range. In few words, build an histogram.
this is my ex code:

#!/usr/bin/perl -w

@value = (48,49,50,46,47,47,35,38,40,42,45,47,48,44,43,46,45,42,43,47);

@sort = sort {$a<=>$b} @value;

$last=$sort[$#sort];

$range = $last - $sort[0];

$classes=5;

$interval = $range / $classes;

$count=0;
$tot=$sort[0];
while ($count<$classes){
# print "$tot\n";
$i=$tot;
$tot=$tot+$interval;
$hash{$i}=$tot;
# print "$tot\n";
# print "---\n";
++$count;
}

$j=1;
@new=$sort[0];
foreach $key (sort{$hash{$a}<=>$hash{$b}} keys %hash){
print "interval $j $key =>> $hash{$key}\n";
push @new,$hash{$key};
++$j;
}

# that's wrong..I know :) but it is just to explain what I am trying
to do
#in fact it gives weird results, as 35 > 40...

for ($im=0;$im<$#sort;++$im){
foreach $key (sort{$hash{$a}<=>$hash{$b}} keys %hash){
if (($sort[$im]>$key) && ($sort[$im]<$hash{$key})){
print "$sort[$im]>$key && $sort[$im]<$hash{$key}\n";
}
}
}

../hystogram.pl

interval 1 35 =>> 38
interval 2 38 =>> 41
interval 3 41 =>> 44
interval 4 44 =>> 47
interval 5 47 =>> 50

what I don't know how to do it is to calculate the frequency of my
@value element respect to the five intervals. I should get an output
like that, with an extra column, which represents the frequency:

interval 1 35 =>> 38 1
interval 2 38 =>> 41 2
interval 3 41 =>> 44 4
interval 4 44 =>> 47 5
interval 5 47 =>> 50 8


thanks for any help

regards

andrea

ps. BTW, I need to feed then gnuplot for making the graph.
 
A

Anno Siegel

Andrea Spitaleri said:
Hi folks,
I am stuck with a problem. Here it is:
I have got an @array1 and I would like to calculate the frequency of
its element by a range. In few words, build an histogram.
this is my ex code:

#!/usr/bin/perl -w

No strict, no warnings.
@value = (48,49,50,46,47,47,35,38,40,42,45,47,48,44,43,46,45,42,43,47);

@sort = sort {$a<=>$b} @value;

$last=$sort[$#sort];

$range = $last - $sort[0];

There is no need to sort the array. All you need is the maximum and
the minimum. List::Util can give you those.
$classes=5;

$interval = $range / $classes;

$count=0;
$tot=$sort[0];
while ($count<$classes){
# print "$tot\n";
$i=$tot;
$tot=$tot+$interval;
$hash{$i}=$tot;
# print "$tot\n";
# print "---\n";
++$count;
}
$j=1;
@new=$sort[0];
foreach $key (sort{$hash{$a}<=>$hash{$b}} keys %hash){
print "interval $j $key =>> $hash{$key}\n";
push @new,$hash{$key};
++$j;
}

# that's wrong..I know :) but it is just to explain what I am trying
to do

Frankly, I'm not sure what you're up to with that code. The verbal
description was clearer :)

In any case, a hash is probably not the structure you want to use
for this problem.

[snip]

There must be lots of ways to do this. I'd define a function that
maps a value onto its class number, given the value, the range and
the number of classes.

sub range_number {
my ( $x, $a, $b, $n) = @_;
int ($x - $a)*$n/( $b - $a);
}

We'll also want a (kind of) inverse of that function: Given a class
number, return the range:

sub range {
my ( $i, $a, $b, $n) = @_;
my $from = $a + $i*($b - $a)/$n;
my $to = $from + ($b - $a)/$n;
( $from, $to);
}

Now build the histogram in an array:
use List::Utils qw( min max);

my @value = (48,49,50,46,47,47,35,38,40,42,45,47,48,44,43,46,45,42,43,47);
my $a = min( @value);
my $b = max( @value);
my $n = 5;

my @histo = ( 0) x $n;
$histo[ range_number( $_, $a, $b, $n)] ++ for @value;

....and show it:

for ( 0 .. $#histo ) {
my ( $from, $to) = range( $_, $a, $b, $n);
print "$_: [$from, $to] -> $histo[ $_]\n";
}

Anno
 
A

Andrea Spitaleri

Now build the histogram in an array:
use List::Utils qw( min max);

it works with List::Util (as you said earlier) :)
except that, it works perfectly.
thanks
andrea
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,147
Messages
2,570,835
Members
47,382
Latest member
MichaleStr

Latest Threads

Top