我想從Java調用R腳本。我已經完成了關於該主題的谷歌搜索,但幾乎所有我看到的結果都需要我爲某些第三方庫添加依賴關係。任何人都可以告訴我一個很好的方法來完成同樣的事情,而不需要添加任何依賴到我的代碼?從java調用R腳本
我正在使用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
第二個編輯: 上面的代碼現在的作品,因爲我跟文森特的建議。但是,爲了讓R腳本有足夠的時間運行,我必須輸入睡眠命令。如果沒有sleep命令,上面的java代碼會拋出一個錯誤,指出Matches.csv文件不存在。我擔心30秒的睡眠時間對於樂器來說太粗糙了。 任何人都可以讓我看看java程序等待R程序有機會創建Matches.csv的代碼嗎?我不願意使用線程工具,因爲我已經讀過設計不佳的線程會導致幾乎不可能進行本地化和修復的錯誤。
關於等待作業結束:你可以看的進程ID終止。您也可以輪詢一些特殊創建的文件的存在(或不存在)。 – Iterator 2012-01-13 23:35:53