Sunny Sunny - 1 month ago 24
Perl Question

Perl: read an array and calculate corresponding percentile

I am trying to code for a perl code that reads a text file with a series of number, calculates, and prints out the numbers that corresponds to the percentiles. I do not have access to the other statistical modules, so I'd like to stick with just pure perl coding. Thanks in advance!

The input text file looks like:

197
98
251
82
51
272
154
167
38
280
157
212
188
88
40
229
228
125
292
235
67
70
127
26
279
.... (and so on)


The code I have is:

#!/usr/bin/perl
use strict;
use warnings;

my @data;

open (my $fh, "<", "testing2.txt")
or die "Cannot open: $!\n";
while (<$fh>){
push @data, $_;
}
close $fh;

my %count;
foreach my $datum (@data) {
++$count{$datum};
}

my %percentile;
my $total = 0;
foreach my $datum (sort { $a <=> $b } keys %count) {
$total += $count{$datum};
$percentile{$datum} = $total / @data;
# percentile subject to change
if ($percentile{$datum} <= 0.10) {
print "$datum : $percentile{$datum}\n\n";
}
}


My desired output:

2 : 0.01
3 : 0.01333
4 : 0.01666
6 : 0.02
8 : 0.03
10 : 0.037
12 : 0.04
14 : 0.05
15 : 0.05333
16 : 0.06
18 : 0.06333
21 : 0.07333
22 : 0.08
25 : 0.09
26 : 0.09666


Where the format is #number from the list : #corresponding percentile

Answer

To store the numer wihtout a newline in @data, just add chomp; before pushing it, or chomp @data; after you've read them all.

If your input file has MSWin style newlines, convert it to *nix style using dos2unix or fromdos.

Also, try to learn how to indent your code, it boosts readability. And consider renaming $total to $running_total, as you use the value as it changes.