使用JAVA程序运行R脚本

4

我是一名R编程新手。我已经创建了一个简单的R脚本,并尝试使用JAVA类来运行它,但我无法做到。

我已经尝试使用Rserve和rJava。使用Rserve,在创建"RConnection"实例后代码执行就停止了,而使用rJava会出现异常"java.lang.UnsatisfiedLinkError: jri.dll: Can't find dependent libraries"。

JAVA类代码如下:

对于rJava:

    import org.rosuda.JRI.Rengine;
public class Temp {

public static void main(String a[]) {
    // Create an R vector in the form of a string.
    String javaVector = "c(1,2,3,4,5)";

    // Start Rengine.
    Rengine engine = new Rengine(new String[] { "--no-save" }, false, null);

    // The vector that was created in JAVA context is stored in 'rVector' which is a variable in R context.
    engine.eval("rVector=" + javaVector);

    //Calculate MEAN of vector using R syntax.
    engine.eval("meanVal=mean(rVector)");

    //Retrieve MEAN value
    double mean = engine.eval("meanVal").asDouble();

    //Print output values
    System.out.println("Mean of given vector is=" + mean);

}
}

对于Rserve:

import org.rosuda.REngine.REXPMismatchException;
import org.rosuda.REngine.Rserve.RConnection;
import org.rosuda.REngine.Rserve.RserveException;
public class Temp {

public static void main(String a[]) {
    RConnection connection = null;
    System.out.println("line 10");
    try {
        // Create a connection to Rserve instance running on default port 6311

        System.out.println("line 15");
        connection = new RConnection();
        System.out.println("line 17");
        //Note four slashes (\\\\) in the path
        connection.eval("source('D:\\\\RExamples\\\\helloworld.R')");
        System.out.println("line 19");
        int num1=10;
        int num2=20;
        int sum=connection.eval("myAdd("+num1+","+num2+")").asInteger();
        System.out.println("The sum is=" + sum);
    } catch (RserveException e) {
        e.printStackTrace();
    } catch (REXPMismatchException e) {
        e.printStackTrace();
    }
}
}

如果我的问题不太清楚,或者您想了解其他信息,请告诉我。先谢谢你。


你是如何配置你的RConnection()的?听起来你需要调查一下配置。也许在RConnection()构造函数内设置一个断点来验证连接。 - Craig
你也可以告诉我其他的方法。这段代码是我从Google找到的。 - Tiya
3个回答

2

连接Java和R有两种不同的方法。

如果您想使用JRI,则必须使用JVM参数-Djava.library.path启动Java程序,该参数指向包含JRI库的文件夹。

例如:

$JAVA_HOME/bin/java  -Djava.library.path=/app/vendor/R/lib/R/library/rJava/jri/ -jar target/myapp.jar

如果您找不到JRI安装目录,请尝试查找JRI SO库:

find / -name "libjri.*"

此外,请确保您在环境中创建了 R_HOME 和 LD_LIBRARY_PATH:
  • R_HOME: 指向您本地的 R 安装目录(例如:/Library/Frameworks/R.framework/Resources)
  • LD_LIBRARY_PATH: 指向 R lib 目录以及 JRI 目录(例如:$LD_LIBRARY_PATH:/app/vendor/R/lib/R/lib:/app/vendor/R/lib/R/bin)
另一方面,如果您想使用 Rserve,您需要在一个 单独的进程 中启动 Rserve,并从您的 Java 进程中创建一个 RConnection。
例如:
        if(LOGGER.isInfoEnabled()) {
            LOGGER.info("Starting RServe process...");
        }
        ProcessBuilder builder = new ProcessBuilder("/bin/sh", "-c", String.format("echo 'library(Rserve);Rserve(FALSE,args=\"--no-save --slave --RS-conf %s\")'|%s --no-save --slave", rserveConf, rexe));
        builder.inheritIO();
        Process rProcess = builder.start();

        if(LOGGER.isInfoEnabled()) {
            LOGGER.info("Waiting for Rserve to start...");
        }
        int execCodeResult = rProcess.waitFor();

        if(execCodeResult != SUCCESS_CODE) {
            LOGGER.error(String.format("Unexpected error code starting RServe: %d", execCodeResult));
        } else {
            LOGGER.error("RServe started successfully");
        }

        if(LOGGER.isInfoEnabled()) {
            LOGGER.info("Opening connection to RServe daemon....");
        }
        REngine engine = new RConnection();
        if(LOGGER.isInfoEnabled()) {
            LOGGER.info(String.format("Obtaining R server version: %d", ((RConnection)engine).getServerVersion()));
        }
        //Perform some engine.parseAndEval("....");

rserveConf是指Rserv配置文件的路径,rexe则是R可执行文件的完整路径。

例如,在我的MacOS电脑上,我可以运行以下命令来启动Rserve:

/bin/sh -c "echo 'library(Rserve);Rserve(FALSE,args=\"--slave --RS-conf /Users/me/Documents/test/rserve.conf\")'|/Library/Frameworks/R.framework/Versions/3.2/Resources/bin/exec/R --no-save --slave"

这个命令会输出类似于这样的内容:
Starting Rserve:
  /Library/Frameworks/R.framework/Resources/bin/R CMD /Library/Frameworks/R.framework/Versions/3.2/Resources/library/Rserve/libs//Rserve --slave 

Rserv started in daemon mode.

在启动Rserve时,请务必指定“--slave”参数。

如果您想查看更多示例,我在我的github上有一个演示项目,使用了JRI和RServe两种方法:

https://github.com/jfcorugedo/RJavaServer


非常感谢您的回复。我已经能够运行我的程序,但现在我遇到了其他问题。请查看http://stackoverflow.com/questions/32581591/run-rscript-from-spring-mvc-with-wildfly-9。 - Tiya
我也回答了那个问题。 - jfcorugedo

1
您只是想调用外部应用程序:以下内容是否有效?
Runtime.getRuntime().exec("Rscript myScript.R"); 

鸣谢stackoverflow自身


请问您能告诉我如何使用它吗?因为在Java类中使用它时,它什么也没有显示。 - Tiya
你可以运行脚本,将输出写入CSV文件。稍后你可以读取该文件以获取脚本的输出结果。请查看给定链接以获取更多详细信息。 - Malaka Gunawardhana

0

另一种选择是使用r的OpenCpu包。 这是一个非常简单的服务器(不幸的是单线程),它通过http接收r函数调用,并将输出作为响应返回。

我已经用它来与java进行接口交互。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接