Tôi muốn gọi một tập lệnh R từ Java. Tôi đã thực hiện tìm kiếm google về chủ đề này, nhưng hầu như tất cả các kết quả tôi đã thấy sẽ yêu cầu tôi thêm một phụ thuộc vào một số thư viện của bên thứ ba. Bất cứ ai có thể cho tôi một cách tốt để thực hiện điều tương tự mà không cần thêm bất kỳ phụ thuộc vào mã của tôi?gọi R script từ java
Tôi đang sử dụng máy tính cửa sổ, vì vậy có lẽ tôi có thể sử dụng dòng lệnh để bắt đầu R (nếu nó chưa được mở) và chạy một tập lệnh R cụ thể. Nhưng tôi chưa bao giờ viết mã dòng lệnh (hoặc gọi nó từ Java) vì vậy tôi sẽ cần các ví dụ mã.
Tôi bao gồm mã mẫu làm việc mà tôi đã viết cho một phương pháp có thể có bên dưới, sử dụng ý tưởng dòng lệnh của tôi. Trong nhận xét nội dòng của tôi bên dưới, bạn có thể thấy rằng Bước Ba trong AssembleDataFile.java bị tôi bỏ trống. Nếu bạn nghĩ rằng bạn có thể làm cho ý tưởng dòng lệnh hoạt động, thì hãy cho tôi biết mã nào cần viết trong Bước Ba.
Ngoài ra, vui lòng đề xuất một cách tiếp cận khác, hy vọng, không liên quan đến việc thêm bất kỳ phụ thuộc nào vào mã của tôi.
Và, như thường lệ, tôi đánh giá cao mọi liên kết bạn có thể đăng lên các bài viết/hướng dẫn/v.v. liên quan đến câu hỏi này.
Dưới đây là những gì tôi có cho đến nay:
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:
Đây là thông báo lỗi đang được ném khi tôi thêm Runtime.getRuntime(). Exec ("Rscript" + rScriptFileName); đến đoạn code trên:
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
THỨ HAI EDIT: Đoạn mã trên hiện đang làm việc vì tôi theo gợi ý của Vincent. Tuy nhiên, tôi phải đưa vào một lệnh ngủ để cung cấp cho kịch bản R đủ thời gian để chạy. Không có lệnh ngủ, mã java ở trên ném một lỗi nói rằng tệp Matches.csv không tồn tại. Tôi lo ngại rằng khoảng thời gian ngủ 30 giây là quá thô của một nhạc cụ. Có ai có thể cho tôi xem mã để chương trình java đợi cho đến khi chương trình R có cơ hội tạo Matches.csv không? Tôi ngần ngại sử dụng các công cụ luồng vì tôi đã đọc rằng các chủ đề được thiết kế kém có thể gây ra các lỗi gần như không thể bản địa hóa và sửa lỗi.
Về chờ đợi cho công việc để hoàn thành: Bạn có thể theo dõi các quá trình ID để chấm dứt. Bạn cũng có thể bình chọn cho sự tồn tại (hoặc không tồn tại) của một số tệp được tạo đặc biệt. – Iterator