Index: quantile.t
===================================================================
--- quantile.t (révision 0)
+++ quantile.t (révision 0)
@@ -0,0 +1,72 @@
+#!/usr/bin/perl
+#==================================================================
+# Author : Djibril Ousmanou
+# Copyright : 2009
+# Update : 20/07/2009
+# AIM : Test quantile type 7 calcul
+#==================================================================
+use strict;
+use warnings;
+use Carp;
+
+use Test::More tests => 15;
+use Statistics::Descriptive;
+
+my @data1 = ( 1 .. 10 );
+my @data2 = (
+ 601, 449, 424, 568, 569, 447, 425, 621, 616, 573, 584, 635, 480, 437,
+ 724, 711, 717, 576, 724, 585, 458, 752, 753, 709, 584, 748, 628, 483,
+ 739, 747, 694, 601, 758, 653, 487, 720, 750, 660, 588, 719, 631, 492,
+ 584, 647, 548, 585, 649, 532, 492, 598, 653, 524, 567, 570, 506, 475,
+ 640, 725, 688, 567, 634, 520, 488, 718, 769, 739, 576, 718, 527, 497,
+ 698, 736, 785, 581, 733, 540, 537, 683, 691, 785, 588, 733, 531, 564,
+ 581, 554, 765, 580, 626, 510, 533, 495, 470, 713, 571, 573, 476, 526,
+ 441, 431, 686, 563, 496, 447, 518
+);
+my @data3 = qw/-9 2 3 44 -10 6 7/;
+
+my %DataTest = (
+ 'First sample test' => {
+ 'Data' => \@data1,
+ 'Test' => {
+ '0' => '1',
+ '1' => '3.25',
+ '2' => '5.5',
+ '3' => '7.75',
+ '4' => '10',
+ },
+ },
+ 'Second sample test' => {
+ 'Data' => \@data2,
+ 'Test' => {
+ '0' => '424',
+ '1' => '526',
+ '2' => '584',
+ '3' => '698',
+ '4' => '785',
+ },
+ },
+ 'Third sample test' => {
+ 'Data' => \@data3,
+ 'Test' => {
+ '0' => '-10',
+ '1' => '-3.5',
+ '2' => '3',
+ '3' => '6.5',
+ '4' => '44',
+ },
+ }
+);
+
+# Test Quantile,
+foreach my $MessageTest ( sort keys %DataTest ) {
+ my $stat = Statistics::Descriptive::Full->new();
+ $stat->add_data( @{ $DataTest{$MessageTest}->{Data} } );
+ for ( 0 .. 4 ) {
+ is(
+ $stat->quantile($_),
+ $DataTest{$MessageTest}->{Test}{$_},
+ $MessageTest . ", Q$_"
+ );
+ }
+}
Index: Descriptive.pm
===================================================================
--- Descriptive.pm (révision 3709)
+++ Descriptive.pm (copie de travail)
@@ -411,6 +411,38 @@
return $self->_median();
}
+sub quantile {
+ my ( $self, $QuantileNumber ) = @_;
+
+ unless ( defined $QuantileNumber and $QuantileNumber =~ m/^0|1|2|3|4$/ ) {
+ carp("Bad quartile type, must be 0, 1, 2, 3 or 4\n");
+ return;
+ }
+
+ $self->sort_data();
+
+ return $self->_data->[0] if ( $QuantileNumber == 0 );
+
+ my $count = $self->count();
+
+ return $self->_data->[ $count - 1 ] if ( $QuantileNumber == 4 );
+
+ my $K_quantile = ( ( $QuantileNumber / 4 ) * ( $count - 1 ) + 1 );
+ my $F_quantile = $K_quantile - POSIX::floor($K_quantile);
+ $K_quantile = POSIX::floor($K_quantile);
+
+ # interpolation
+ my $aK_quantile = $self->_data->[ $K_quantile - 1 ];
+ return $aK_quantile if ( $F_quantile == 0 );
+ my $aKPlus_quantile = $self->_data->[$K_quantile];
+
+ # Calcul quantile
+ my $quantile = $aK_quantile
+ + ( $F_quantile * ( $aKPlus_quantile - $aK_quantile ) );
+
+ return $quantile;
+}
+
sub _real_calc_trimmed_mean
{
my $self = shift;
@@ -916,6 +948,35 @@
If the percentile method is called in a list context then it will
also return the index of the percentile.
+=item $x = $stat->quantile($Type);
+
+Sorts the data and returns estimates of underlying distribution quantiles based on one
+or two order statistics from the supplied elements.
+
+This method use the same algorithm as Excel and R language (quantile B<type 7>).
+
+The generic function quantile produces sample quantiles corresponding to the given probabilities.
+
+B<$Type> is an integer value between 0 to 4 :
+
+ 0 => zero quartile (Q0) : minimal value
+ 1 => first quartile (Q1) : lower quartile = lowest cut off (25%) of data = 25th percentile
+ 2 => second quartile (Q2) : median = it cuts data set in half = 50th percentile
+ 3 => third quartile (Q3) : upper quartile = highest cut off (25%) of data, or lowest 75% = 75th percentile
+ 4 => fourth quartile (Q4) : maximal value
+
+Exemple :
+
+ my @data = (1..10);
+ my $stat = Statistics::Descriptive::Full->new();
+ $stat->add_data(@data);
+ print $stat->quantile(0); # => 1
+ print $stat->quantile(1); # => 3.25
+ print $stat->quantile(2); # => 5.5
+ print $stat->quantile(3); # => 7.75
+ print $stat->quantile(4); # => 10
+
+
=item $stat->median();
Sorts the data and returns the median value of the data.