R言語の実行環境を構築し、
rJavaを介してJavaからRを呼び出せるまでの設定を行います。
構築するのは Ubuntu12.04 LTS 上です。
jdkは既に入っているとします。
R言語のインストール
まずはR言語をインストール
$ sudo apt-get update
$ sudo apt-get install r-base
$ sudo apt-get install r-cran-*
で簡単に完了。
apt-getでは本体は /use/lib/R 以下。
$HOME/R 以下にもライブラリなどが入る。
パスを通した方が良いらしいので通す。
$ export R_HOME=/usr/lib/R
参考 : RjpWiki - Rのインストール
rJavaのインストール
JVM関連のパスをRに設定
$ R CMD javareconf
Rを起動して、rJavaをインストール。'J' だけ大文字なので注意。
$ R
> install.packages('rJava')
ミラーサーバを選ぶ画面が出るので適当に選ぶ。( 確かJapan(tsukuba)を選択 )
これで、/usr/lib/R/site-library/ にrJavaフォルダが出来ている。
$HOME/R の奥深くにもrJavaフォルダが出来ている。
(別環境では、/usr/lib/R/site-liblary/ 以下にrJavaフォルダができないこともある。
その時でも、$HOME/R 以下の JRI.jar を利用することで問題なく連携した。)
参考 : Qiita - jjzak - rjavaのインストールメモ&rincanterの設定(OSX,Ubuntu)
Eclipseで動作確認
Eclipseを入れていなかったので、今回はpleiadesを普通にインストール
$ sudo apt-get install pleiades
改めて動作確認。まずEclipseで普通にプロジェクト作成。
作成途中の「外部jar追加」 で、JRI.jar を参照。
/usr/lib/R/site-library/rJava/jri/JRI.jar
($HOME/R 以下でも大丈夫)
プロジェクトが出来たら、「デバッグ→デバッグの構成」を開いて、
「引数→VMの引数」に以下を追加
-Djava.library.path=.:/usr/lib/R/site-library/rJava/jri/
また、同じ「デバッグの構成」内の「環境」に、
$R_HOME /usr/lib/R
を追加。
追加しないとRは何処だと怒られる。(上で設定した$R_HOMEは何処へ?)
これで基本的な設定は完了。
mainに以下の参考サイトまんまのコードを書いてデバッグ実行。
package com.test.r;
import org.rosuda.JRI.REXP;
import org.rosuda.JRI.Rengine;
public class RSample {
public static void main(String[] args) {
Rengine engine = new Rengine(new String[]{"--no-save"}, false, null);
engine.assign("a", new int[]{36});
REXP result = engine.eval("sqrt(a)");
System.out.println(result.asDouble());
engine.end();
}
}
コンソールに6.0が出れば完了。
参考 : Symfoware - Ubuntu 12.04にEclipseをインストールする
binfalse - Talking R through Java
hamadakoichi blog - Java R Interface (JRI) を用い 統計解析環境 R を Java から使用する
使い方
R←→Javaのやり取りは、Rengineというクラスで行います。
assign()でデータを渡し、
eval()で関数を実行するらしい。
assignには数値や配列を渡せる。
行列を直接受け取るメソッドが無いので、代わりにREXPというクラスを渡す。
REXP クラスとは、RとJavaでのデータ受け渡しに使用されるデータクラスで、
内部でデータ変換をしているものと思われる。
REXPにはstaticなcreateXXX()メソッドがあります。
その中に、Doubleの2次元配列を受け取りREXPを吐く仕様があるので、
多分これを利用して行列REXPを作成し、Rに行列を渡せると思われる。
evalの戻り値もREXPクラス。
REXP には asXXXX()というメソッドが定義されていて、
それによってJava上でXXXの形式で結果が受け取れるらしい。
asVector()とかasXXXMatrix() という関数があるので、
行列関係の取得も可能。
注意
RengineはSingletonらしく、
2回目以降はnewではなくRengine.getMainEngine();で
インスタンスを取得する必要がある。