前回の続きです。
今回はRCLを使って、Common LispからRの関数を呼んでグラフを描いてみます。
インストール
こちらに書いてある通り、Quicklispでインストールできました。
> (ql:quickload :rcl)
使い方
詳しいマニュアルは無いみたいです。
RCL examples に短いサンプル、 Comparing RCL with Rpy にRPyとの比較があります。
あとインストール先の 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)