问题场景
项目一直在用Java开发,但接下来要在Java中调用R的脚本执行某一制图任务,笔者采用JRI方式,先记录一下。
笔者环境
OS:win-10-64位
JDK:1.8.0_31(32位)如果不知道怎么看32位还是64位,打开cmd窗口输入java -version 命令, 如果有64字眼说明是64位,如果没有则是32位。
R:R-3.4.1 官网:https://www.r-project.org/
注意:安装R-3.4.1一般会带有32位或者64位两个版本,安装时请与你的JDK版本一致不是操作系统版本。
安装步骤
a 自行安装jdk,并配置好path,classpath,home等环境变量
b 在官网下载对应的R包,安装完毕后也需要配置R_HOME,path,classpath变量
新建系统变量R_HOME:D:\programFile\R\R-3.4.1
PATH: %R_HOME%\bin\i386;%R_HOME%\library\rJava\jri\i386
CLASSPATH: %R_HOME%\library\rJava\jri;%R_HOME%\library\rJava\jri\JRI.jar
c 打开R自带的IDE敲入‘install.packages(“rJava”)’,回车选择安装的镜像下载安装rJava
d 安装完毕敲入‘library(rJava)’回车,如果不报错则安装成功,如果报错,检查一下R包版本与你的JDK版是否一致。
R调用Java
打开R自带的IDE运行图片中的代码
Java调用R
调用之前把D:\programFile\R\R-3.4.1\library\rJava\jri目录下的JRI.jar、JRIEngine.jar、REngine.jar3个jar包导入你的工程中。
package rjava;
import org.rosuda.JRI.Rengine;
import java.lang.reflect.Field;
/**
* Created on 2017/9/19
* Author: youxingyang.
*/
public class Hello {
static {
//此方法如果配置了path变量D:\programFile\R\R-3.4.1\library\rJava\jri\i386就不用调用了,因为设置过了。
loadJRILibDynamically();
}
/**
* 如果环境变量没有配置则可以替代每次运行时设置的VM参数'-Djava.library.path="D:\programFile\R\R-3.4.1\library\rJava\jri\i386"'
*/
private static void loadJRILibDynamically() {
try {
System.setProperty("java.library.path", System.getProperty("java.library.path")
+ ";D:\\programFile\\R\\R-3.4.1\\library\\rJava\\jri\\i386");
Field fieldSysPath = ClassLoader.class.getDeclaredField("sys_paths");
fieldSysPath.setAccessible(true);
fieldSysPath.set(null, null);
System.loadLibrary("JRI");
} catch (Exception e) {
// do nothing for exception
}
}
public static void test(){
Rengine re = new Rengine(new String[] {"--vanilla"}, false, null);
if(!re.waitForR()){
System.out.println("Cannot load R");
return;
}
//打印R版本
String version = re.eval("R.version.string").asString();
System.out.println(version);
//打印一维数组
int[] apple = re.eval("array(1:20, c(3))").asIntArray();
for (Integer a : apple) {
System.out.print(a + " ");
}
System.out.println("执行脚本里的函数");
//脚本变量赋值fn, 调用R脚本,test.r里的函数自己写一下吧
re.assign("fn", "E:\\1报告数据\\2代用药\\全自动化-x\\LongLung作图\\test.r");
//用source命令将脚本中的函数加载到R环境中,后续可以直接调用
re.eval("source(fn)");
//直接调用fn脚本里定义的无参函数
REXP rexp = re.eval("test1()");
double d = rexp.asDouble();
System.out.println(d);
//调用有参函数
REXP rexp1 = re.eval("test_add(5, 7, 8)");
double add = rexp1.asDouble();
System.out.println(add);
re.end();
}
public static void main(String[] args) {
test();
}
}