今回は CategoryDataste のサブタイプ BoxAndWhiskerCategoryDataset とそれを要求するチャート BoxAndWhiskerChart を見ていきます*1。
「Whisker」はヒゲのことで、BoxAndWhisker 図は誤差を含めてチャートにする際によく用いられます。
BoxAndWhiskerCategoryDataset のインスタンスを取得する
BoxAndWhiskerCategoryDataset には、1つのカテゴリごとに次の統計値が設定できます(日本語が正しいかどうか不明):
- 平均値 (mean)
- 中間値 (median)
- Q1 値 (lower quartile)
- Q3 値 (upper quartile)
- 最小正則値 (min regular value)
- 最大正則値 (max regular value)
- 最小の外れ値 (min outlier)
- 最大の外れ値 (max outlier)
ただし、これら全ての値を設定する必要はないようです。 というより、データさえ用意すれば、これらの値を計算してくれるユーティリティがあります(知らずに自分で平均値とか計算しちゃったヨwww)
統計値を計算するユーティリティ・メソッドは org.jfree.data.statistics.BoxAndWhiskerCalculator#calculateBoxAndWhiskerStatistics() です。 これを使用したサンプルコードを見てみましょう。
このサンプルでは
- 100個の乱数を発生して(rand.nextDouble())、それを data1 に格納
- BoxAndWhiskerCategoryDataset のインスタンス DefaultBoxAndWhiskerCategoryDataset のインスタンスを生成
- BoxAndWhiskerCalculator.calculateBoxAndWhiskerStatistics() メソッドに data1 を渡して統計値を計算
- 計算した統計値(正確には BoxAndWhiskerItem オブジェクト)を BoxAndWhiskerCategoryDataset オブジェクトへセット
という手順でデータセットを作成しています:
def rand = new Random(1L) int n = 100 def data1 = [] n.times{ data1 << rand.nextDouble() } def dataset = new DefaultBoxAndWhiskerCategoryDataset() dataset.add(BoxAndWhiskerCalculator.calculateBoxAndWhiskerStatistics(data1), 'row key', '1')
データセットの作成はコレで完了です。 他に統計値に関するユーティリティが必要な場合は、org.jfree.data.statistics パッケージにあるクラスのドキュメントを見てみるとよいかと思います。
BoxAndWhiskerChart
ChartFactory.createBoxAndWhiskerChart('Box and Whisker Chart (Category Dataset)', 'n', 'r^n', dataset, true)
- 上記のサンプルの作成に、さらにあれこれデータを加えてます。
統計値を Groovy で計算してみる
最初、BoxAndWhiskerCalculator#calculateBoxAndWhiskerStatistics() メソッドなんて便利なものがあるのを知らなかったので、自分で統計値を計算してしまった。 そのまま削除するのも気が引けるので載っけておきます。 Groovy の練習程度に思っておこうかな。
データは Double の配列で作成し、乱数で初期化。 それを用いて (Defaut)BoxAndWhiskerCategoryDataset のデータを設定しています。 createBoxAndWhiskerItem() メソッドは後で実装。
def rand = new Random(1L) int n = 100 assert n % 4 == 0 // Q1, Q3 を取得するのに面倒になるので n は4の倍数に制限 def data1 = [] for(i in 0..<n){ data1 << rand.nextDouble() } data.sort() // データの順序が変わってしまうけど、えいやと sort def dataset = new DefaultBoxAndWhiskerCategoryDataset() dataset.add(createBoxAndWhiskerItem(data), 'row key', 'r')
平均値の計算
まずは平均値。 sum() メソッドを使えば何てことなし。
def mean(List data){ return data.sum() / data.size() }
中間値
次は中間値。 これらは、データをソートさえしていれば超w簡単。
def median(List data){ // data は sort 済み int half = data.size().intdiv(2) - 1 return data[half] }
Q1, Q3
Q1, Q3 値も中間値と大差なし。 返り値は [Q1, Q3] のリスト
def quartiles(List data){ // data は sort 済み int quarter = data.size().intdiv(4) return [data[quarter-1], data[quarter*3-1]] }
最小値、最大値
同じく最大値、最小値。
def boundaries(List] data){ // data は sort 済み return [data[0], data[data.size()-1]] }
BoxAndWhiskerItem
さーて、以上のメソッドを使って BoxAndWhiskerItem インスタンスを作成するためのデータのリストを作成:
def createBoxAndWhiskerItem(List data){ def mean = mean(data) def median = median(data) def (q1, q3) = quartiles(data) def (min, max) = boundaries(data) return [mean, median, q1, q3, min, max, null, null] }
リストの最後に指定している2つの null は外れ値の最小値と最大値。 指定しなくても例外が投げられたりはしない模様。
結構大変そうな統計値の計算も、それぞれが数行(ものによっては1行!)で書けてしまうという素晴らしさ。 天晴れ Groovy!
- 作者: Dierk Konig,Andrew Glover,Paul King,Guillaume Laforge,Jon Skeet,杉浦孝,櫻井正樹,須江信洋,関谷和愛,佐野徹郎,寺沢尚史
- 出版社/メーカー: 毎日コミュニケーションズ
- 発売日: 2008/09/27
- メディア: 単行本(ソフトカバー)
- 購入: 5人 クリック: 146回
- この商品を含むブログ (121件) を見る
*1:BoxAndWhiskerChart は、BoxAndWhiskerCategoryDataset の他にも BoxAndWhiskerXYDataset から作成することもできます。 これは後ほど。