2014/05/29(木)Perl Data Language 統計編 #02 「度数分布表と棒グラフ」

http://www.tokyo-tosho.co.jp/download/DL02122.zip

↑のデータを使って実際の問題も解いていきましょう。まずは第1章の練習問題の2)から。

度数分布表はPDLを使わずにテキストで出力しました。 CSVの読み込みは「PDL::IO::Misc」でできるのですが、CSV中の文字列が値ゼロになるので、文字列を含む場合はText::CSVあたりで読み込まざるをえないですね。(このへんはRに比べると少し不便)

#!/usr/bin/env perl

use strict;
use warnings;
use feature qw/say/;
use utf8;
use open qw/:encoding(utf-8) :std/;
use Text::CSV;
use Text::UnicodeTable::Simple;
use PDL::Lite;
use PDL::Graphics::PLplot;
use DDP filters => { -external => [ 'PDL' ] };

my $infile = 'weather.csv';

my $csv = Text::CSV->new({
    auto_diag => 1,
    binary    => 1,
});

open(my $fh, '<:encoding(cp932)', $infile) or die $!;

my $kaze_cnt = 0;
my %kaze_direction_freq_of;

while ( my $row = $csv->getline($fh) )
{
    my ($hizuke, $kion, $shitsudo, $nissho, $kaze_direction) = @{ $row };

    next unless $hizuke =~ /^[0-9]+$/;

    $kaze_direction_freq_of{$kaze_direction}++;
    $kaze_cnt++ if defined $kaze_direction;
}

close($fh);

my $table = Text::UnicodeTable::Simple->new;
$table->set_header(qw/風向き 度数 相対度数/);

for my $direction (keys %kaze_direction_freq_of)
{
    my $freq = $kaze_direction_freq_of{$direction};
    $table->add_row( $direction, $freq, sprintf(&quot;%.3f&quot;, $freq / $kaze_cnt) );
}

say '度数分布表:';
say $table;
say '(相対度数は少数第三位まで表示)';

my $pl = PDL::Graphics::PLplot->new(
    DEV   => 'xcairo',
    XLAB  => '風向き',
    YLAB  => '度数',
    YTICK => 2,
    NYSUB => 2,
    COLOR => 'BLUE',
);

my @labels = keys %kaze_direction_freq_of;
my $values = pdl map { $kaze_direction_freq_of{$_} } @labels;

$pl->bargraph(@labels, $values, BOX => [ 0, scalar @labels, 0, $values->max + 1 ]);

$pl->close;
度数分布表:
.--------+------+----------.
| 風向き | 度数 | 相対度数 |
+--------+------+----------+
| 南東   |    1 |    0.032 |
| 西北西 |    2 |    0.065 |
| 東北東 |    2 |    0.065 |
| 南西   |    1 |    0.032 |
| 北西   |   10 |    0.323 |
| 北北西 |   15 |    0.484 |
'--------+------+----------'

(相対度数は少数第三位まで表示)

棒グラフ