从java调用R脚本 [英] calling R script from java

查看:482
本文介绍了从java调用R脚本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想从Java调用R脚本。我已经对该主题进行了Google搜索,但是我看到的几乎所有结果都需要我添加一个依赖关系到一些第三方库。任何人都可以告诉我一个好的方法来完成同样的事情,而不添加任何依赖到我的代码?

I would like to call an R script from Java. I have done google searches on the topic, but almost all of the results I have seen would require me to add a dependency to some third party library. Can anyone show me a good way to accomplish the same thing without adding any dependencies to my code?

我使用的是windows机器,所以也许我可以使用命令行启动R(如果尚未打开)并运行特定的R脚本。但我从来没有写过命令行代码(或从Java中调用它),所以我需要代码示例。

I am using a windows machine, so perhaps I might use the command line to start R (if it is not already open) and to run a specific R script. But I have never written command line code (or called it from Java) so I would need code examples.

我包括一个可能的方法下面,使用我的命令行的想法。在下面的内嵌评论中,您可以看到AssembleDataFile.java中的第三步 被我特意留空。如果你认为你可以使命令行的想法工作,那么请告诉我在第三步中写什么代码。

I am including working sample code that I wrote for one possible approach below, using my command line idea. In my in-line-comments below, you can see that Step Three in AssembleDataFile.java is intentionally left blank by me. If you think that you can make the command line idea work, then please show me what code to write in Step Three.

此外,随时建议另一种方法,希望不会对我的代码添加任何更多的依赖。

Also, feel free to suggest another approach that, hopefully, does not involve adding any more dependencies to my code.

并且,一如既往,我非常感谢您可能发表的文章/教程/ etc相关的任何链接这个问题。

And, as always, I very much appreciate any links you might post to articles/tutorials/etc related to this question.

这是我到目前为止:

AssembleDataFile.java

AssembleDataFile.java

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;

public class AssembleDataFile {
static String delimiter;
static String localPath = "C:\\test\\cr\\";
static String[][] myDataArray;

public static void main(String[] args) {
    String inputPath = localPath+"pd\\";
    String fileName = "MSData.txt";
    delimiter = "\\t";

    // Step One: Import data in two parts
    try {
        // 1A: get length of data file
        BufferedReader br1 = new BufferedReader(new FileReader(inputPath+fileName));
        int numRows = 0;
        int numCols = 0;
        String currentRow;
        while ((currentRow = br1.readLine()) != null) {
            numRows += 1;
            numCols = currentRow.split(delimiter).length;}
        br1.close();
        //1B: populate data into array
        myDataArray = new String[numRows][numCols+1];
        BufferedReader br2 = new BufferedReader(new FileReader(inputPath+fileName));
        String eachRow;
        int rowIdx = 0;
        while ((eachRow = br2.readLine()) != null) {
            String[] splitRow = eachRow.split(delimiter);
            for(int z = 0;z < splitRow.length;z++){myDataArray[rowIdx][z] = splitRow[z];}
            rowIdx += 1;}
        br2.close();

        // Step Two: Write data to csv
        String rPath = localPath+"r\\";
        String sFileName = rPath+"2colData.csv";
        PrintWriter outputWriter = new PrintWriter(sFileName);
        for(int q = 0;q < myDataArray.length; q++){
            outputWriter.println(myDataArray[q][8]+", "+myDataArray[q][9]);
        }
        outputWriter.close();

        //Step Three: Call R script named My_R_Script.R that uses 2ColData.csv as input
        // not sure how to write this code.  Can anyone help me write this part?
        // For what it is worth, one of the R scripts that I intend to call is included below
        //
        //added the following lines here, per Vincent's suggestion:
            String rScriptFileName = rPath+"My_R_Script.R";
        Runtime.getRuntime().exec("mypathto\\R\\bin\\Rscript "+rScriptFileName);
        //
        //

        //Step Four: Import data from R and put it into myDataArray's empty last column
        try {Thread.sleep(30000);}//make this thread sleep for 30 seconds while R creates the needed file
        catch (InterruptedException e) {e.printStackTrace();}
        String matchFileName = rPath+"Matches.csv";
        BufferedReader br3 = new BufferedReader(new FileReader(matchFileName));
        String thisRow;
        int rowIndex = 0;
        while ((thisRow = br3.readLine()) != null) {
            String[] splitRow = thisRow.split(delimiter);
            myDataArray[rowIndex][numCols] = splitRow[0];
            rowIndex += 1;}
        br3.close();

        //Step Five: Check work by printing out one row from myDataArray
        //Note that the printout has one more column than the input file had.
        for(int u = 0;u<=numCols;u++){System.out.println(String.valueOf(myDataArray[1][u]));}
    }
    catch (FileNotFoundException e) {e.printStackTrace();}
    catch (IOException ie){ie.printStackTrace();}
}
}

My_R_Script.R

My_R_Script.R

myCSV <- read.csv(file="2colData.csv",head=TRUE,sep=",")  
pts = SpatialPoints(myCSV)
Codes = readShapeSpatial("mypath/myshapefile.shp")  
write.csv(ZipCodes$F[overlay(pts,Codes)], "Matches.csv", quote=FALSE, row.names=FALSE)






EDIT:

这是错误当我添加Runtime.getRuntime()时抛出的消息exec(Rscript+ rScriptFileName);到上面的代码:



Here is the error message that is being thrown when I add Runtime.getRuntime().exec("Rscript "+rScriptFileName); to the code above:

java.io.IOException: Cannot run program "Rscript": CreateProcess error=2, The system cannot find the file specified
at java.lang.ProcessBuilder.start(Unknown Source)
at java.lang.Runtime.exec(Unknown Source)
at java.lang.Runtime.exec(Unknown Source)
at java.lang.Runtime.exec(Unknown Source)
at AssembleDataFile.main(AssembleDataFile.java:52)
Caused by: java.io.IOException: CreateProcess error=2, The system cannot find the file specified
at java.lang.ProcessImpl.create(Native Method)
at java.lang.ProcessImpl.<init>(Unknown Source)
at java.lang.ProcessImpl.start(Unknown Source)
... 5 more    






第二个编辑:
上面的代码现在可以工作,因为我遵循Vincent的建议。然而,我不得不放入一个睡眠命令,以给予R脚本足够的时间运行。没有sleep命令,上面的java代码引发一个错误,说Matches.csv文件不存在。我担心30秒的睡眠时间对仪器太粗糙。 任何人都可以显示代码,让java程序等到R程序有机会创建Matches.csv? 我不喜欢使用线程工具,因为我读过设计不当的线程可能会导致几乎无法本地化和修复的错误。


SECOND The code above now works because I followed Vincent's suggestions. However, I had to put in a sleep command in order to give the R script enough time to run. Without the sleep command, the java code above throws an error saying that the Matches.csv file does not exist. I am concerned that a 30 second sleep period is too rough of an instrument. Can anyone show me code that gets the java program to wait until the R program has a chance to create Matches.csv? I hesitate to use thread tools because I have read that poorly designed threads can cause bugs that are nearly impossible to localize and fix.

推荐答案

您只想调用外部应用程序:以下工作?

You just want to call an external application: wouldn't the following work?

Runtime.getRuntime().exec("Rscript myScript.R"); 

这篇关于从java调用R脚本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆