当前位置: 首页 > 面试题库 >

从Java调用R脚本

祖浩淼
2023-03-14
问题内容

我想从Java调用R脚本。我已经对该主题进行了google搜索,但是我看到的几乎所有结果都需要我向某些第三方库添加依赖项。任何人都可以向我展示一种在不添加任何依赖项的情况下完成同一件事的好方法吗?

我正在使用Windows计算机,因此也许我可以使用命令行来启动R(如果尚未打开)并运行特定的R脚本。但是我从未写过命令行代码(或从Java调用过),因此我需要代码示例。

我将使用命令行思路包含为以下一种可能的方法编写的工作示例代码。在下面的在线注释中,您可以看到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

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)

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

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的建议。但是,我必须输入sleep命令才能给R脚本足够的运行时间。如果没有sleep命令,则上面的Java代码将引发错误,指出Matches.csv文件不存在。我担心30秒的睡眠时间太长了。
谁能给我展示让Java程序等待R程序有机会创建Matches.csv的代码吗?
我很犹豫使用线程工具,因为我读到设计不良的线程可能会导致几乎无法本地化和修复的错误。


问题答案:

您只想调用一个外部应用程序:以下工作行不通?

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


 类似资料:
  • 问题内容: 我对rpy2和R都是新手。 我基本上有一个R脚本script.R,其中包含函数,如rfunc(folder)。它与我的python脚本位于同一目录中。我想从Python调用它,然后启动其功能之一。我不需要此R函数的任何输出。我知道它必须非常基础,但是我找不到R脚本调用python代码的示例。我目前在Python中做什么: 我在源代码行中遇到错误: 我完全不明白我给它的参数不是字符串,而

  • 我在尝试从Java运行R脚本时遇到了一个问题。我真的在互联网上寻找这个问题的答案,但什么都不管用。 求你帮帮我 这是java代码 以下是当我添加Runtime.getRuntime(). exec("Rcript"rScriptFileName)时抛出的错误消息:

  • 问题内容: 如何在Java中调用node.js并将console.log值保存在String变量中? 问题答案: Java应用程序可能与正在运行的Node.JS应用程序进行通信。例如,您可以在可用端口上运行Node.JS应用,而Java应用可以通过tcp套接字与之通信。 http://nodejs.org/api/net.html 或者,您可以创建一个http服务器并公开Java应用程序可以使用的

  • 问题内容: 如何从外壳脚本内部执行Java方法? 问题答案: 您只能调用该方法。设计您的方法,使其调用所需的方法。 当我说 调用 方法时,您不会显式调用它。调用它是Java程序的唯一入口点。 如果您的班级看起来像: 您可以使用以下命令行在您可以找到的目录中调用from (如果您位于下面显示的结构的目录中): 如果要从其他目录(请参见下面的目录结构)执行此操作,则必须设置类路径。 为了清楚起见,请采

  • 我需要从AnyLogic调用R脚本。我有一个代理“传感器”,它将从一个特定的位置发送一个随机文件到一个R脚本,然后R脚本将分析该文件,并让我们知道该文件的类型(图像、声音、文本等) 请让我知道如何从AnyLogic调用R脚本。。

  • 问题内容: 我在String变量中有一个Rscript,我想从Java程序执行它并将一些变量传递给它。如果我独立执行该R脚本,则可以正常工作。我已通过使用Python程序将所有脚本转义,从而将该R脚本转换为一行,如下所示: 我将打印出的字符串用完,并将其存储在String变量中,然后使用以下代码执行,但它根本不起作用。我正在传递和可变到上述R脚本。 上面的代码可以与bash shell脚本一起正常