PostgreSQL Advent Calendar 12/6 です。
ネタを決めるにあたり、analyticsをテーマに何かないものかと探してみたら、
PL/R(R手続き型言語)なるものがあるそうで。
Rは統計解析分野で人気のプログラミング言語。
オープンソースで、コミュニティの活動も活発なようです。
参考:R Advent Calendar 2011 : ATND
では、PL/Rを導入して、ちょこっと触ってみます。
Install
今回構築した環境は下記。
・Mac OS X 10.6 Snow Leopard
・gcc 4.2.1
・postgresql 9.0.4
・R 2.14.0
・plr-8.3.0.13
Windows,Linuxへのインストールは下記をご参考
R と PostgreSQL - RjpWiki
まずRをインストール。
(macのhomebrewを使用)
brew install r Error: This formula requires a fortran compiler失敗。fortranコンパイラをインストールして再チャレンジ。
brew install gfortran brew install rOK。インストール時に一般的なインストール先に
リンクさせた方がいいよとメッセージが出るので、
sudo ln -s "/usr/local/Cellar/r/2.14.0/R.framework" /Library/FrameworksこれでRのインストールは完了。
なお、パッケージインストールも可能。
参考:R for Mac OS X
次にPL/Rをインストール。
ソースは→ http://joeconway.com/plr/ から入手。
su - postgres cd /path-to-postgres_source/contrib #ここにPL/Rのソースを配置 tar zxf plr-8.3.0.13.tar.gz cd plr export R_HOME=/Library/Frameworks/R.framework/Resources make make installPL/Rのインストール完了。テスト用のDBを作成して言語を登録。
createdb r_test cd /path-to-pgsql/contrib psql r_test < plr.sql psql -c "SELECT * FROM pg_language WHERE lanName = 'plr'" r_test #確認これで導入完了。
Try working
PL/Rのドキュメントにある集約関数をテストしてみます。
(中央値を返す集約関数medianを作成)
create or replace function r_median(_float8) returns float as ' median(arg1) ' language 'plr'; CREATE AGGREGATE median ( sfunc = plr_array_accum, basetype = float8, stype = _float8, finalfunc = r_median ); SELECT median(v) FROM (values(1.0),(2.5),(5.7),(3.4),(-0.9)) AS t(v); -- => select 2.5集約関数はfloat8を配列に集約して最後にr_median(_float8)を呼び出し、
Rの関数medianを計算しています。
ポイントはデータ型の違い。
R言語はベクトル処理言語であり、データはベクトルで持ちます。
例えば、上記のmedianの計算は、Rでは下記のように行います。
x <- c(1.0, 2.5, 5.7, 3.4, -0.9) #ベクトルを作成してxに代入 median(x) # => [1] 2.5postgresからRへの引数の受け渡しについては、
・スカラ ⇒ 単一要素のベクトル(例外あり)
・ 一次元配列 ⇒ 複数要素のベクトル
・二次元配列 ⇒ 行列
・三次元配列 ⇒ 三次元配列
・三次元以上の配列 ⇒ サポートせず
・ 複合型 ⇒ データフレーム
となります。
参考:Passing Data Values
では最後に、統計解析の基礎として相関係数を計算する関数を作成してみます。
参考:R-Source
CREATE OR REPLACE FUNCTION correlation(_float8, _float8) RETURNS float8 AS ' cor(arg1, arg2) ' LANGUAGE 'plr';列xと列yの相関係数を計算する場合は下記で。
SELECT correlation(array_agg(x),array_agg(y)) FROM (values(0.7,1.9),(-1.6,0.8),(-0.2,1.1),(-1.2,0.1),(-0.1,-0.1) ,(3.4,4.4),(3.7,5.5),(0.8,1.6),(0.0,4.6),(2.0,3.4)) AS t(x,y); -- => select 0.795102...
以上、簡単にさわってみました。
それほど敷居は高くないように感じますが、どういう用途に使ったものか...
Be continued
応用編に続く ...のか?
Next
明日はs87さんです。よろしくお願いします。