一昨日作ったPL/R用ストアド関数を使い、昨日のTSVファイル経由とは違う方法によるPostgreSQLのデータ読み込みのメモ。また、普通はRコンソールから立ち上げるプロット窓(グラフィックウィンドウ)をPL/Rでも出すことができたので ↓ 合わせて紹介します。実行環境は昨日までと同様Windows 7 32bit + PostgreSQL Portable 9.4 + R 3.1.2 + PL/R 8.3.0.16。

pg.spi.exec関数でPostgreSQLのデータ読み込み
PL/R User's Guide : Database Access and Support Functions : Normal Supportに、PL/Rからクエリを実行するための関数が多く載っています。これを使うと、通常のRからPostgreSQLへの接続と異なり(1)追加のパッケージ不要、(2)データベース接続・切断の処理不要、と手軽です。ただし(2)の裏返しとして、クエリの対象にできるのはカレントの(PL/Rを実行している)データベースに限られます。

↓ 関数のうちpg.spi.execを使う例。引数にSQL文字列を入れて実行すると、結果が自動的にRのデータフレームになって返ります。コードの下の画像では「変数へ何か代入する式を丸括弧でくくると、結果を出力する」というRコンソールでの動作と同じかを確認していますが、その後、丸括孤でくくらなくとも、最終行の実行内容の結果が自動的にNOTICEに出力されると判明。
DO $_d_$
BEGIN
PERFORM test.plr_do($_r_$
    dat = pg.spi.exec('
        SELECT * FROM test.dummy -- any SQL statement
    ')
$_r_$);
END $_d_$;

クエリツールからRのグラフィックウィンドウを起動してプロット
↓ を実行した時の様子が、冒頭の画像です。windows関数でグラフィックウィンドウを立ち上げ、ランダムな位置・大きさ・色の円をプロットするテスト。3秒後に自動で閉じます。ただしこれが動くのはポータブル版だけ。通常の、サービスとしてPostgreSQLが機能する場合は何も実行されませんでした。
DO $_d_$
BEGIN
PERFORM test.plr_do($_r_$
    dat = pg.spi.exec('
        SELECT random(), random()
        FROM generate_series(1, 100)
    ')
    n = nrow(dat)
    windows(height=5, width=5, xpos=300, ypos=300)
    plot(dat,
        cex = runif(n) * 5 + 5, 
        col = adjustcolor(topo.colors(n), 0.2),
        pch = 16)
    Sys.sleep(3)
    graphics.off()
$_r_$);
END $_d_$;

注意点、デモ動画
pg.spi.exec関数はPL/R専用で、ストアド関数をきちんと作ってその中で使うことしか想定されていません。今回の自作ストアド関数plr_doRのコードをevalに渡しており、正直、その中にpg.spi.execを入れて動くとは思いませんでした。結果的に一応動いたもののSQLに誤りがあると即サーバが落ち、実用は難しそうです。

また、実行結果をNOTICEとしてクエリツール内に出す部分は、どうもRが最後に実行した式や関数の結果がそのまま来てしまうらしく、途中経過だけ表示したい場合などは面倒。

プロット窓は、今回の方法で立ち上げると「手動で操作できない」困ったものになります。同じPostgreSQLのセッションでグラフィックをPL/Rで閉じる処理をするか(ストアド関数または今回の擬似DO文で)、セッション自体を閉じて初めてデスクトップから消えるという…。上の例で、3秒後に自動的に閉じるようにしたのはこのため。タスクマネージャには、応答なしのアプリケーションとしてプロット窓が現れますが、それを強制終了するとサーバも落ちます。

下のデモ動画は、最初にプロット窓を3秒後に自動で閉じるコード実行、次が自動で閉じないコードで、その結果プロット窓を操作できなくなり、再びgraphics.off()を含むコードを実行した様子です。
≫ Link : demo_plr_plot_window.webm