http://jliblog.com/archives/10java
R是統計計算的強大工具,而JAVA是作應用系統的主流語言,二者自然具備整合的須要。關於整合,一方面,R中能夠建立JAVA對象調用JAVA方法,另外一方面,JAVA中能夠轉換R的數據類型調用R的函數,互相取長補短。如今也有一個項目JGR,用JAVA作R的圖形界面,能夠實現高亮顯示自動補全等,還能讓JAVA和R互相調用。服務器
關於R中調用JAVA,我想主要是爲了利用其面向對象的特性,畢竟R語言近來很致力於向面向對象發展,有個很好的項目rJava能夠實現,在www.rforge.net/rJava上。R中調JAVA對我彷佛意義不大,本文主要介紹JAVA中調用R。全部測試都在Windows XP、R2.10.1和JDK1.6下完成。eclipse
JAVA很適合開發應用系統,可是數學建模和計算能力非其所長,若是該系統須要進行大量的統計或者優化的計算,調用R是一種很好的方式。JAVA負責系統的構建,R用來作運算引擎,從而實現應用型和分析性相結合的系統。函數
首先要介紹的是Rserve的方式,這是一個基於TCP/IP的服務器,經過二進制協議傳輸數據,能夠提供遠程鏈接,使得客戶端語言可以調用R。目前Rserve做爲一個package發佈在CRAN上,能夠直接使用install.packages("Rserve")進行安裝。須要使用時在R控制檯下加載該包,而後輸入命令Rserve(),開啓服務器,就能夠供客戶端調用。工具
其客戶端能夠有多種,這裏只介紹JAVA客戶端。最先的客戶端包是JRclient,在www.rosuda.org/Rserve上還能夠下載到,可是如今該項目所有移到了www.rforge.net/Rserve,使用REngine做客戶端(和JRI一致),在該網站下能夠下載到REngine.jar和RserveEngine.jar兩個文件。若是用eclipse開發的話,在工程屬性中導入這兩個外部的jar包,就能夠正常使用了。oop
一個簡單的例子:性能
public class rtest { public static void main(String[] args) throws REXPMismatchException, REngineException { RConnection c = new RConnection(); REXP x = c.eval("R.version.string"); System.out.println(x.asString()); } }
首先創建一個新的鏈接,而後就可使用eval之類的方法將R中的表達式傳到服務器端,經過R求值後傳回JAVA中REXP類型的變量,而後打印出來,整個過程很是簡單。因爲不須要對R進行初始化,所以速度會比較快。在其餘系統下能夠同時創建多個鏈接,可是在Windows下只容許同時打開一個鏈接,後續的鏈接都會共有相同的命名空間。官網上不建議在Windows下使用Rserve,由於會喪失不少性能,他們推薦能夠考慮DCOM的方式。不過DCOM那個工程沒有現成的jar包可用,其實若是是拿R作分析系統中的運算引擎,單鏈接夠用了。測試
另外一種方式是JRI,全名是Java/R Interface,這是一種徹底不一樣的方式,經過調用R的動態連接庫從而利用R中的函數等。目前該項目已經成了rJava的子項目,再也不提供單獨的JRI的版本。所以使用時簡單地經過install.packages("rJava")安裝rJava就行,在安裝文件夾中,能夠看到一個jri的子文件夾,裏面有自帶的例子能夠用來測試。優化
裝好後要修改系統的環境變量,在PATH中添加%R_HOME%bin和%R_HOME%libraryrJavajri,注意R_HOME的路徑要正確,重啓系統使之生效。使用時一樣在eclipse裏導入外部的jar包(在www.rforge.net/rJava下載JRI.jar、REngine.jar和JRIEngine.jar這三個文件),在rJava包安裝目錄下的jriexamples裏有現成的例子(rtest.java和rtest2.java),能夠測試是否成功。網站
以前個人電腦上一直存在一個很奇怪的問題,測試第一個例子時在「Creating Rengine (with arguments)」的時候就停住了,第二個例子中一個JAVA框很快閃一下就消失了,控制檯中沒有任何提示。打開JGR也是一閃即逝。在網上查了好久,只有一個印度哥們也遇到過相似的問題,並且沒有找到解決辦法。估計應該是實現RMainLoopCallbacks時出了問題,可是找不到緣由,後來卸載了R2.9.0重裝了R2.10.1,而且經過install.packages安裝,終於沒問題了,多是主程序和Package之間的版本衝突,之後記住所有用install.packages來安裝package了。
關於客戶端服務器的方式和動態連接庫的方式,各有所長,按照須要選用。我的經驗,無論使用哪一種方式,設計時儘可能少進行頻繁的數據的交互,在邏輯上把系統和計算分開,使得R成爲一個純粹的運算引擎。