2013年7月22日月曜日

Common LispでR (RCLを使ってみる)

前回の続きです。

今回はRCLを使って、Common LispからRの関数を呼んでグラフを描いてみます。

インストール

こちらに書いてある通り、Quicklispでインストールできました。

> (ql:quickload :rcl)

使い方

詳しいマニュアルは無いみたいです。

RCL examples に短いサンプル、 Comparing RCL with RpyRPyとの比較があります。

あとインストール先の examples/ 以下にサンプルコードがいくつかあります。

グラフ描画のコード

サンプルコードを参考にしながら何となく書いてみました。

(asdf:oos 'asdf:load-op :rcl)
(r:r-init)
(r:enable-rcl-syntax)

(defun plot-num-of-animals (animal-state)
  (let ((day (mapcar #'car animal-state))
        (num (mapcar (lambda (x) (length (cadr x))) animal-state)))
    [plot day num :type "o" :pch 20 :ylim [c 0 [max num]]
         :main "動物の個体数" :xlab "経過日数" :ylab "動物の個体数"]))

(defun plot-hist (animal-state)
  (let ((max-x 1.0)
        (max-y 160))
    (mapc (lambda (state)
            (let ((day (car state))
                  (rate (cadr state)))
              [hist rate :breaks [seq 0 max-x 0.02]
                   :ylim [c 0 max-y] :main (format nil "~7d 日後" day)
                   :col "gray" :xlab "直進率" :ylab "動物の個体数"]))
          animal-state)))

(defun animal-state->png (out-dir animal-state)
  (r:with-device ((format nil "~A/%03d" out-dir) :png :width 400 :height 300)
    (plot-num-of-animals animal-state)
    (plot-hist animal-state)))

角括弧[] の部分でRの関数を呼んでいます。 Lispのコードと混ぜて書けるのがおもしろいです。

あと、r:with-device で描画のコードを包むのがLispっぽくて好きです。 (Rだと デバイス開く、描画、デバイス閉じる、と手続き的)

描画

描画を実行します。

まずは前回同様、20万日分シミュレーションを走らせ、1万日間隔で動物の状態をdumpします。

> (defparameter *dump* (dump-animal-state 200000 10000))

グラフを描画します。

> (animal-state->png "Rplot" *dump*)

Rplot/ 以下に連番のpngファイルが生成されます。

前回同様のグラフができました。

感想

今回試した範囲では割と良い感じに使えました。 Rに慣れた人が、Common Lispでデータをいじっていて、ちょっとグラフを描いて確かめたい、 みたいなときに便利かも。

ちなみにCommon Lispでグラフを描く方法は他にもいろいろあるみたいです。 (CLiki: plotting)

0 件のコメント:

コメントを投稿