Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 217
  • Last Modified:

final total number of times value in column 3 > 15 then total number of times both column 3 & 4 are above 15 perl

I'm using the script below. Initially it was intended to find the total number of times the last column exceeded a value separated in 6 categories. Now there is only one category. The other main difference is I am switching columns 3 & 4 because I have a different file format. The problem is when I changed switch -2, -1 and/or $forecasted $observed in the perl script it didn't seem to output the correct values. A sample input file is attached.

So this is what I want the script to do. 1. Count the total number of times column 3 exceeds a value of 15  and 2. count the total number of time where both column 3 & 4 in the same row exceed 15.

sample new script with my attempt at the correct solution

use strict;

my @observed;
my @same;
while( <> ) {
   chomp;
   my($forecasted, $observed) = (split)[-1,-2];
   my $observedCategory = valueToCategory($observed);
   my $forecastedCategory = valueToCategory($forecasted);
   $observed[ $observedCategory ]++;
   $same[ $observedCategory ]++ if $observedCategory == $forecastedCategory;
}

foreach my $category(1) {
   my $observed   = $observed[$category]  || 0;
   my $same       = $same[$category]      || 0;
   printf("$category %3d %3d %5.1f\n", $observed, $same, $observed ? ($same*100)/$observed : 0);
}


sub valueToCategory {
   my($value) = @_;

   my $category;
   if( $value > 15 )    { $category = 2 }
   

   return $category;
}

Open in new window





output file format

1 123 133
2 13  2
3 0 0
4 0 0
5 0 0
6 0 0

new output file format
2  14 4
so4pap.txt
0
libertyforall2
Asked:
libertyforall2
  • 2
2 Solutions
 
oheilCommented:
Here is my proposal:

use strict;

my @observed;
my @same;
while( <> ) {
   chomp;
   my($forecasted, $observed) = (split)[-2,-1];      #this line changed
   my $observedCategory = valueToCategory($observed);
   my $forecastedCategory = valueToCategory($forecasted);
   $observed[ $observedCategory ]++;
   $same[ $observedCategory ]++ if $observedCategory == $forecastedCategory;
}

foreach my $category( (1,2) ) {         #this line changed
   my $observed   = $observed[$category]  || 0;
   my $same       = $same[$category]      || 0;
   printf("$category %3d %3d %5.1f\n", $observed, $same, $observed ? ($same*100)/$observed : 0);
}


sub valueToCategory {
   my($value) = @_;

   my $category = 1;       #this line changed
   if( $value > 15 )    { $category = 2 }


   return $category;
}

Open in new window



Using your example data, the output is:
1 206 172  83.5
2  33   4  12.1

which means:
category 1 is forecasted <= 15 : 206 in total,  172 are forecasted <= 15 but observed > 15
category 2 is forecasted > 15 : 33 in total,  4 are forecasted > 15 and observed > 15

Thats what you needed?

Oli



0
 
oheilCommented:
Sorry, this :

category 1 is forecasted <= 15 : 206 in total,  172 are forecasted <= 15 but observed > 15

is wrong.

True is:

category 1 is forecasted <= 15 : 206 in total,  172 are forecasted <= 15 and observed <= 15

Oli
0
 
libertyforall2Author Commented:
Great!
0

Featured Post

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now