ライブラリを使わずにJavaからRを使う

統計解析器RをJavaで使う。
RをJavaで扱うライブラリもあるようだけど、
ライブラリの中を理解するのが大変そうなので、
ライブラリを使わずにRの出力をJavaで受け取りたい。

というわけで、やってみた。

環境

Ubuntu 10.04
Netbeans 6.8

コード

help()コマンドを実行した時の出力を受け取る。

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;

/**
 *
 * @author Syu_Syu
 */
public class Rcmd {
    public String commander()throws IOException {
        String result = new String();

        ProcessBuilder builder = new ProcessBuilder("/usr/bin/R","-q","--no-save");
        Process process = builder.start();
        OutputStream os = process.getOutputStream();
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(os));

        bw.write("help()");
        bw.flush();
        bw.close();

        InputStream is = process.getInputStream();
        BufferedReader br = new BufferedReader(new InputStreamReader(is));
        String line_tmp = new String();
        String line = new String();
        while((line_tmp = br.readLine()) != null){
            line += line_tmp +"\n";
            System.out.println(line_tmp);
        }
        br.close();

        InputStream stream = process.getErrorStream();
        while(true){
            int c = stream.read();
            if(c == -1){
                stream.close();
                break;
            }
            System.out.print((char)c);
        }

        result = line;
        return result;
    }
}

ライセンス表示の省略

Rを起動すると以下の文章が表示される。

R version 2.10.1 (2009-12-14)
Copyright (C) 2009 The R Foundation for Statistical Computing
ISBN 3-900051-07-0

Rは、自由なソフトウェアであり、「完全に無保証」です。 
一定の条件に従えば、自由にこれを再配布することができます。 
配布条件の詳細に関しては、'license()'あるいは'licence()'と入力してください。 

Rは多くの貢献者による共同プロジェクトです。 
詳しくは'contributors()'と入力してください。 
また、RやRのパッケージを出版物で引用する際の形式については
'citation()'と入力してください。 

'demo()'と入力すればデモをみることができます。 
'help()'とすればオンラインヘルプが出ます。 
'help.start()'でHTMLブラウザによるヘルプがみられます。 
'q()'と入力すればRを終了します。 

標準出力をStringで取ってきているので、この文章も取ってきてしまう。
そこで、非表示にするオプションを使う。

ProcessBuilder builder = new ProcessBuilder("/usr/bin/R","-q","--no-save");

この"-q","--no-save"がオプション。
 -qでライセンスを非表示にできる。
 --no-saveで実行したRを保存しない設定にしている。

複数のコマンド入力

以下のコードでhelp()コマンドを入力している。

bw.write("help()");
bw.flush();
bw.close();

例えば、続けてgetwd()コマンドを入力したい時は、以下のようにする。

bw.write("help()\n");
bw.flush();
bw.write("getwd()");
bw.flush();
bw.close();

または、以下のように、\nで繋げて書いても良い。

bw.write("help()\ngetwd()");
bw.flush();
bw.close();

エラー処理は必須

以下のコードは、エラー処理として絶対に必要。

        InputStream stream = process.getErrorStream();
        while(true){
            int c = stream.read();
            if(c == -1){
                stream.close();
                break;
            }
            System.out.print((char)c);
        }

このエラー処理がないと、うまく動かない。

おわり

取ってきたStringは、以下のようにコマンドも出力されている。

> getwd()
[1] "/home/username/NetBeansProjects/projectname"
> 

そのため、別のプログラムで必要な部分だけ抽出してやる必要がある。