вызов сценария R из java

Я хотел бы вызвать сценарий R из Java. Я выполнил поиск в 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)

EDIT:
Вот сообщение об ошибке, которое выдается, когда я добавляю 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    

ВТОРОЕ РЕДАКТИРОВАНИЕ: Приведенный выше код теперь работает, потому что я следовал советам Винсента. Однако мне пришлось ввести команду сна, чтобы дать сценарию R достаточно времени для запуска. Без команды сна приведенный выше код java выдает ошибку, говоря, что файл Matches.csv не существует. Меня беспокоит, что 30-секундный период сна слишком груб для инструмента. Может ли кто-нибудь показать мне код, который заставляет java-программу ждать, пока программа R не сможет создать Matches.csv? Я не решаюсь использовать инструменты потоков, потому что я читал, что плохо спроектированные потоки могут вызывать ошибки, которые практически невозможно локализовать и исправить.

18
задан CodeMed 13 January 2012 в 23:02
поделиться