Rsession讓Java調用R更簡單
R的極客理想系列文章,涵蓋了R的思想,使用,工具,創新等的一系列要點,以我個人的學習和體驗去詮釋R的強大。
R語言作爲統計學一門語言,一直在小衆領域閃耀着光芒。直到大數據的爆發,R語言變成了一門炙手可熱的數據分析的利器。隨着越來越多的工程背景的人的加入,R語言的社區在迅速擴大成長。現在已不僅僅是統計領域,教育,銀行,電商,互聯網….都在使用R語言。
要成爲有理想的極客,我們不能停留在語法上,要掌握牢固的數學,概率,統計知識,同時還要有創新精神,把R語言發揮到各個領域。讓我們一起動起來吧,開始R的極客理想。
關於作者:
- 張丹(Conan), 程序員Java,R,PHP,Javascript
- weibo:@Conan_Z
- blog: http://blog.fens.me
- email: [email protected]
轉載請註明出處:
http://blog.fens.me/r-rserve-rsession/
前言
寫了好幾篇關於Rserve的文章了,Rserve作爲R語言的通信接口,已經成爲了R語言擴展的重要通道。大數據時代的到來,讓原本小衆的R語言,不經意間擠進了開發語言前20名。
同時,具有多種編程語言背景的IT工程師們,開始進入R的社區,幫助R語言快速進化。Rserve提供了一個通信的接口,通過封裝可以讓R引擎嵌入到其他語言裏。
目錄
- Rsession介紹
- Rsession下載
- 用Eclipse構建Rsession項目
- Rsession的API介紹
- Rserve服務器系統環境
- Rsession使用
1. Rsession介紹
Rsession提供了一種簡單的方式,讓Java可以訪問遠程或本地的Rserve實例。Rsession是對Rserve的封裝,提供了更高層的API接口,包括Rserve服務器控制,多會話機制,並支持Windows環境。
另一個R和Java通信的庫JRI,並不支持多會話機制。關於R和Java通信的其他文章,請參考:解惑rJava R與Java的高速通道, Rserve與Java的跨平臺通信
Rsession項目主頁:https://code.google.com/p/rsession/
2. Rsession下載
系統環境
- Win7 64bit
- R: 3.0.1 x86_64-w64-mingw32/x64 b4bit
發行包下載:解壓縮就可以直接使用了
http://rsession.googlecode.com/files/libRsession.zip
包括3個jar包:REngine.jar, Rserve.jar, Rsession.jar
源代碼下載:(SVN)
http://rsession.googlecode.com/svn/trunk/Rsession/
~ cd d:\workspace\java
~ svn checkout http://rsession.googlecode.com/svn/trunk/ rsession-read-only
~ mv rsession-read-only rsession
~ cd rsession\Rsession
項目是通過Ant構建的,我們可以自己編譯,打包。
~ ant
Buildfile: d:\workspace\java\rsession\Rsession\build.xml
clean:
clean-dist:
init:
[mkdir] Created dir: d:\workspace\java\rsession\Rsession\build
[mkdir] Created dir: d:\workspace\java\rsession\Rsession\dist\lib
resource:
[copy] Copying 28 files to d:\workspace\java\rsession\Rsession\dist\lib
[copy] Copied 12 empty directories to 1 empty directory under d:\workspace\java\rsession\Rsession\dist\lib
compile:
[javac] d:\workspace\java\rsession\Rsession\build.xml:33: warning: 'includeantruntime' was not set, defaulting to bu
ild.sysclasspath=last; set to false for repeatable builds
[javac] Compiling 10 source files to d:\workspace\java\rsession\Rsession\build
dist:
[jar] Building jar: d:\workspace\java\rsession\Rsession\dist\lib\Rsession.jar
[zip] Building zip: d:\workspace\java\rsession\Rsession\dist\libRsession.zip
BUILD SUCCESSFUL
Total time: 2 seconds
在目錄:d:\workspace\java\rsession\Rsession\dist\下面,生成發行包,libRsession.zip
3. 用Eclipse構建Rsession項目
用Eclipse構建Rsession項目,複製Rsession\dist\目錄文件到項目,並加載到項目的環境變量。
4. Rsession的API介紹
查看類庫:Rsession.jar
接口類
- BusyListener: Notify the state of R engine
- EvalListener: Notify the evaluation of R expression
- Logger: Support R messages printing
- UpdateObjectsListener: Notify the changing of R environment objects
功能類
- Rdaemon: RServe的守護進程
- RLogPanel: 顯示R日誌的空間
- RObjectsPanel: 顯示R變量的控件
- RserverConf: 連接Rserve實例的配置文件
- Rsession: 連接Rserve實例
- StartRserve: 啓動本地的Rserve
5. Rserve服務器系統環境
服務器系統環境
- Linux: Ubuntu 12.04.2 LTS 64bit
- R: 3.0.1 x86_64-pc-linux-gnu
- Rserve: Rserve v1.7-1
Rserve環境
- IP: 192.168.1.201,允許遠程訪問
- 端口: 6311
- 登陸認證: 用戶名:conan, 密碼:conan
- 字符編碼: utf-8
Rserve服務器環境與文章中 Rserve的R語言客戶端RSclient 配置相同。
6. Rsession使用
建立遠程連接
RserverConf rconf = new RserverConf("192.168.1.201", 6311, "conan", "conan", new Properties());
Rsession s = Rsession.newInstanceTry(System.out, rconf);
執行R腳本
double[] rand = s.eval("rnorm(5)").asDoubles();
for(double ran:rand){
System.out.print(ran+",");
}
//日誌輸出
[eval] rnorm(5)
org.rosuda.REngine.REXPDouble@5f934ad[5]{0.08779203903807914,0.039929482749452114,-0.8788534039223883,-0.8875740206608903,-0.8493446334021442}
0.08779203903807914,0.039929482749452114,-0.8788534039223883,-0.8875740206608903,-0.8493446334021442
R創建對象並保存環境
// 創建一個R對象
s.set("demo", Math.random());
s.eval("ls()");
// 保存R環境到本地到文件
s.save(new File("./output/save.Rdata"), "demo");
// 刪除R對象demo
s.rm("demo");
s.eval("ls()");
// 從文件加載R環境
s.load(new File("./output/save.Rdata"));
s.eval("ls()");
s.eval("print(demo)");
//日誌輸出
[set] demo
創建一個data.frame對象
s.set("df", new double[][] { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 }, { 10, 11, 12 } }, "x1", "x2", "x3");
double df$x1_3 = s.eval("df$x1[3]").asDouble();
System.out.println(df$x1_3);
s.rm("df");
//日誌輸出
[set] df
在本地生成一個圖形文件
s.toJPEG(new File("./output/plot.png"), 400, 400, "plot(rnorm(10))");
//日誌輸出
[set] plotfile_1100539400
以HTML格式輸出
String html = s.asHTML("summary(rnorm(100))");
System.out.println(html);
//日誌輸出
<html> Min. 1st Qu. Median Mean 3rd Qu. Max. <br/>-2.332000 -0.659900 0.036920 0.004485 0.665800 2.517000 </html>
以文本格式輸出
String txt = s.asString("summary(rnorm(100))"); // format in text
System.out.println(txt);
//日誌輸出
Min. 1st Qu. Median Mean 3rd Qu. Max.
-3.19700 -0.65330 -0.09893 -0.07190 0.53300 2.29000
安裝新類庫
System.out.println(s.installPackage("sensitivity", true));
//日誌輸出
trying to load package sensitivity
package sensitivity is not installed.
package sensitivity not yet installed.
[eval] install.packages('sensitivity',repos='http://cran.cict.fr/',dependencies=TRUE)
org.rosuda.REngine.REXPNull@4d47c5fc
request package sensitivity install...
package sensitivity is not installed.
! package sensitivity installation failed.
Impossible to install package sensitivity !
查看完整的文件:RsessionDemo.java
~ vi RsessionDemo.java
package org.conan.r.rsession;
import java.io.File;
import java.util.Properties;
import org.math.R.RserverConf;
import org.math.R.Rsession;
import org.rosuda.REngine.REXPMismatchException;
public class RsessionDemo {
public static void main(String args[]) throws REXPMismatchException {
RserverConf rconf = new RserverConf("192.168.1.201", 6311, "conan", "conan", new Properties());
Rsession s = Rsession.newInstanceTry(System.out, rconf);
// 執行R腳本
double[] rand = s.eval("rnorm(5)").asDoubles();
System.out.println(rand);
// 創建一個R對象
s.set("demo", Math.random());
s.eval("ls()");
// 保存R運行時狀態到文件
s.save(new File("./output/save.Rdata"), "demo");
// 刪除R對象demo
s.rm("demo");
s.eval("ls()");
// 從文件加載R環境
s.load(new File("./output/save.Rdata"));
s.eval("ls()");
s.eval("print(demo)");
// 創建一個data.frame對象
s.set("df", new double[][] { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 }, { 10, 11, 12 } }, "x1", "x2", "x3");
double df$x1_3 = s.eval("df$x1[3]").asDouble();
System.out.println(df$x1_3);
s.rm("df");
// 生成一個圖形文件
s.eval("getwd()");
s.toJPEG(new File("./output/plot.png"), 400, 400, "plot(rnorm(10))");
// 以HTML格式輸出
String html = s.asHTML("summary(rnorm(100))");
System.out.println(html);
// 以文本格式輸出
String txt = s.asString("summary(rnorm(100))");
System.out.println(txt);
// 安裝新類庫
System.out.println(s.installPackage("sensitivity", true));
s.end();
}
}
對比Rserve的JavaAPI(參考文章:Rserve與Java的跨平臺通信),是不是感覺Rsession再友好呢!
我們在使用RStudio時,任務管理器中也可以看到rsession的進程!猜一下,RStudio也在使用rsession做程序接口。
動起手來,創造就在自己手中。