JAVA很適合開發應用系統,但是數學建模和計算能力非其所長,如果該系統需要進行大量的統計或者優化的計算,調用R是一種很好的方式。JAVA負責系統的構建,R用來做運算引擎,從而實現應用型和分析性相結合的系統。
Rserve方式
Rserve作為一個package發布在CRAN上,可以直接使用install.packages("Rserve")進行安裝。需要使用時在R控制臺下加載該包,然后輸入命令Rserve(),開啟服務器,就可以供客戶端調用。
客戶端,下載REngine.jar和RserveEngine.jar兩個文件。
啟動"Rserve"


import org.rosuda.REngine.REXP;import org.rosuda.REngine.Rserve.RConnection;public class RserveHandler {/** * application entry point. */public static void main(String[] args) {try {RConnection conn = new RConnection();REXP ex = conn.eval("R.version.string");System.out.PRintln(ex.asString());} catch (Exception e) {e.printStackTrace();}}}
JRI方式
Java/R Interface,通過調用R的動態鏈接庫從而利用R中的函數。通過install.packages("rJava")安裝rJava就行,在安裝文件夾中,可以看到一個jri的子文件夾,里面有自帶的例子可以用來測試。
配置環境變量:

PATH .;%JAVA_HOME%/bin;%M2_HOME%/bin;%R_HOME%/bin/x64;%R_HOME%/library/rJava/jri/x64


package com.nsecn.rns;import java.awt.FileDialog;import java.awt.Frame;import java.io.BufferedReader;import java.io.InputStreamReader;import java.util.Enumeration;import org.rosuda.JRI.REXP;import org.rosuda.JRI.RList;import org.rosuda.JRI.RMainLoopCallbacks;import org.rosuda.JRI.RVector;import org.rosuda.JRI.Rengine;class TextConsole implements RMainLoopCallbacks { public void rWriteConsole(Rengine re, String text, int oType) { System.out.print(text); } public void rBusy(Rengine re, int which) { System.out.println("rBusy(" + which + ")"); } public String rReadConsole(Rengine re, String prompt, int addToHistory) { System.out.print(prompt); try { BufferedReader br = new BufferedReader(new InputStreamReader( System.in)); String s = br.readLine(); return (s == null || s.length() == 0) ? s : s + "/n"; } catch (Exception e) { System.out.println("jriReadConsole exception: " + e.getMessage()); } return null; } public void rShowMessage(Rengine re, String message) { System.out.println("rShowMessage /"" + message + "/""); } @SuppressWarnings("deprecation") public String rChooseFile(Rengine re, int newFile) { FileDialog fd = new FileDialog(new Frame(), (newFile == 0) ? "Select a file" : "Select a new file", (newFile == 0) ? FileDialog.LOAD : FileDialog.SAVE); fd.show(); String res = null; if (fd.getDirectory() != null) res = fd.getDirectory(); if (fd.getFile() != null) res = (res == null) ? fd.getFile() : (res + fd.getFile()); return res; } public void rFlushConsole(Rengine re) { } public void rLoadHistory(Rengine re, String filename) { } public void rSaveHistory(Rengine re, String filename) { }}public class JIRunit { /** * Application entry point. */ public static void main(String[] args) { // just making sure we have the right version of everything if (!Rengine.versionCheck()) { System.err.println("** Version mismatch - Java files don't match library version."); System.exit(1); } System.out.println("Creating Rengine (with arguments)"); // 1) we pass the arguments from the command line // 2) we won't use the main loop at first, we'll start it later // (that's the "false" as second argument) // 3) the callbacks are implemented by the TextConsole class above Rengine re = new Rengine(args, false, new TextConsole()); System.out.println("Rengine created, waiting for R"); // the engine creates R is a new thread, so we should wait until it's // ready if (!re.waitForR()) { System.out.println("Cannot load R"); return; } /* * High-level API - do not use RNI methods unless there is no other way * to accomplish what you want */ try { REXP x; re.eval("data(iris)", false); System.out.println(x = re.eval("iris")); // generic vectors are RVector to accomodate names RVector v = x.asVector(); if (v.getNames() != null) { System.out.println("has names:"); for (Enumeration<?> e = v.getNames().elements(); e .hasMoreElements();) { System.out.println(e.nextElement()); } } // for compatibility with Rserve we allow casting of vectors to // lists RList vl = x.asList(); String[] k = vl.keys(); if (k != null) { System.out.println("and once again from the list:"); int i = 0; while (i < k.length) System.out.println(k[i++]); } // get boolean array System.out.println(x = re.eval("iris[[1]]>mean(iris[[1]])")); // R knows about TRUE/FALSE/NA, so we cannot use boolean[] this way // instead, we use int[] which is more convenient (and what R uses // internally anyway) int[] bi = x.asIntArray(); { int i = 0; while (i < bi.length) { System.out.print(bi[i] == 0 ? "F " : (bi[i] == 1 ? "T " : "NA ")); i++; } System.out.println(""); } // push a boolean array boolean by[] = { true, false, false }; re.assign("bool", by); System.out.println(x = re.eval("bool")); // asBool returns the first element of the array as RBool // (mostly useful for boolean arrays of the length 1). is should // return true System.out.println("isTRUE? " + x.asBool().isTRUE()); // now for a real dotted-pair list: System.out.println(x = re.eval("pairlist(a=1,b='foo',c=1:5)")); RList l = x.asList(); if (l != null) { int i = 0; String[] a = l.keys(); System.out.println("Keys:"); while (i < a.length) { System.out.println(a[i++]); } System.out.println("Contents:"); i = 0; while (i < a.length) { System.out.println(l.at(i++)); } } System.out.println(re.eval("sqrt(36)")); } catch (Exception e) { System.out.println("EX:" + e); e.printStackTrace(); } // Part 2 - low-level API - for illustration purposes only! // System.exit(0); // simple assignment like a<-"hello" (env=0 means use R_GlobalEnv) long xp1 = re.rn
package com.nsecn.rns;import java.awt.Dimension;import java.awt.FileDialog;import java.io.BufferedReader;import java.io.InputStreamReader;import java.io.PrintStream;import javax.swing.JFrame;import javax.swing.JScrollPane;import javax.swing.JTextArea;import org.rosuda.JRI.RConsoleOutputStream;import org.rosuda.JRI.RMainLoopCallbacks;import org.rosuda.JRI.Rengine;class TextConsole2 implements RMainLoopCallbacks { JFrame frame; public JTextArea textarea = new JTextArea(); @SuppressWarnings("deprecation") public TextConsole2() { frame = new JFrame(); frame.getContentPane().add(new JScrollPane(textarea)); frame.setSize(new Dimension(800, 600)); frame.show(); } public void rWriteConsole(Rengine re, String text, int oType) { textarea.append(text); } public void rBusy(Rengine re, int which) { System.out.println("rBusy(" + which + ")"); } public String rReadConsole(Rengine re, String prompt, int addToHistory) { System.out.print(prompt); try { BufferedReader br = new BufferedReader(new InputStreamReader( System.in)); String s = br.readLine(); return (s == null || s.length() == 0) ? s : s + "/n"; } catch (Exception e) { System.out.println("jriReadConsole exception: " + e.getMessage()); } return null; } public void rShowMessage(Rengine re, String message) { System.out.println("rShowMessage /"" + message + "/""); } @SuppressWarnings("deprecation") public String rChooseFile(Rengine re, int newFile) { FileDialog fd = new FileDialog(frame, (newFile == 0) ? "Select a file" : "Select a new file", (newFile == 0) ? FileDialog.LOAD : FileDialog.SAVE); fd.show(); String res = null; if (fd.getDirectory() != null) res = fd.getDirectory(); if (fd.getFile() != null) res = (res == null) ? fd.getFile() : (res + fd.getFile()); return res; } public void rFlushConsole(Rengine re) { } public void rLoadHistory(Rengine re, String filename) { } public void rSaveHistory(Rengine re, String filename) { }}public class JRIano { /** * Application entry point. */ public static void main(String[] args) { System.out.println("Press <Enter> to continue (time to attach the debugger if necessary)"); try { System.in.read(); } catch (Exception e) { } System.out.println("Creating Rengine (with arguments)"); Rengine re = new Rengine(args, true, new TextConsole2()); System.out.println("Rengine created, waiting for R"); if (!re.waitForR()) { System.out.println("Cannot load R"); return; } System.out.println("re-routing stdout/err into R console"); System.setOut(new PrintStream(new RConsoleOutputStream(re, 0))); System.setErr(new PrintStream(new RConsoleOutputStream(re, 1))); System.out.println("Letting go; use main loop from now on"); }}
新聞熱點
疑難解答