Я экспериментировал с вызовом R внутри Java с использованиемRengine.eval()
метода rjava в. Мне удалось запустить простой скрипт «hello world» и выполнить простые анализы, если я придерживаюсь однострочных операторов.Как я могу оценить/выполнить многострочный R скрипт, используя rjava
Однако, когда я пытаюсь выполнить многострочный оператор (например, назначая определение функции), я не могу найти последовательный способ заставить его работать.
По словам ведущего в этом видеоролике Devoxx: youtube video, (по значению 36:52) несколько сценариев могут быть выполнены путем оценки каждой строки отдельно. То есть, если я не интерпретирую образец кода, который он показывает на слайде в вышеупомянутый момент.
Поскольку такой подход меня не подводит, я написал тест блока, который не показывает рабочий подход ...
Может кто-нибудь с большим опытом пролил свет на это? Поведение для каждого тестового теста включено в комментарии. (Блок кода ниже)
Любая помощь очень ценится
КР
Саймон
import org.junit.Test;
import org.rosuda.JRI.RMainLoopCallbacks;
import org.rosuda.JRI.Rengine;
public class RJavaSanityCheck {
private static Rengine engine;
@Test
public void singleStatementMultiLinesMultiEval(){
Rengine engine = getEngine();
engine.eval("myfunc <- function(x){");
engine.eval("z <- x");
engine.eval("return (x)");
engine.eval("}");
engine.eval("print(myfunc(1))");
//FAIL: Throws two errors:
// Error: object 'x' not found
// Error in print(myfunc(1)) : could not find function "myfunc"
}
@Test
public void singleStatementMultiLinesSingleEvalWindows(){
Rengine engine = getEngine();
engine.eval("myfunc <- function(x){\r\nz <- x\r\nreturn(x)\r\n}\r\n");
engine.eval("print(myfunc(1))");
engine.end();
//FAIL: Prints nothing and throws an error:
// Error in print(myfunc(1)) : could not find function "myfunc"
}
@Test
public void singleStatementMultiLinesSingleEvalLinux(){
Rengine engine = getEngine();
engine.eval("myfunc <- function(x){\nz <- x\nreturn(x)\n}");
engine.eval("print(myfunc(1))");
engine.end();
//SUCCESS: Prints 1
}
@Test
public void multiStatementsMultiLineSingleEvalLinux(){
Rengine engine = getEngine();
engine.eval("print(\"Hello\")\nprint(\"World!\")");
engine.end();
//FAIL: Prints "hello" but not "world!"
}
@Test
public void multiStatementsMultiLineSingleEvalWindows(){
Rengine engine = getEngine();
engine.eval("print(\"Hello\")\r\nprint(\"World!\")");
engine.end();
//FAIL: Prints nothing
}
@Test
public void MultiStatementsMultiEval(){
Rengine engine = getEngine();
engine.eval("print(\"Hello\")");
engine.eval("print(\"World!\")");
engine.end();
//SUCCESS: Prints Hello World!
}
private static Rengine getEngine(){
if (engine == null){
if (!Rengine.versionCheck()){
throw new RuntimeException("Version mismatch!");
}
engine = new Rengine(new String[]{"--vanilla"}, false, new RMainLoopCallbacks() {
@Override
public void rWriteConsole(Rengine rengine, String s, int i) {
System.out.println(s);
}
@Override
public void rBusy(Rengine rengine, int i) {
//Not implemented
}
@Override
public String rReadConsole(Rengine rengine, String s, int i) {
//Not implemented
return null;
}
@Override
public void rShowMessage(Rengine rengine, String s) {
System.out.println(s);
}
@Override
public String rChooseFile(Rengine rengine, int i) {
//Not implemented
return null;
}
@Override
public void rFlushConsole(Rengine rengine) {
//Not implemented
}
@Override
public void rSaveHistory(Rengine rengine, String s) {
//Not implemented
}
@Override
public void rLoadHistory(Rengine rengine, String s) {
//Not implemented
}
});
if (!engine.waitForR()){
throw new RuntimeException("Loading error!");
}
}
return engine;
}
}
Вы можете использовать точку с запятой для выполнения нескольких команд в одной строке в R, поэтому я подозреваю, что это сработает, если вы замените все '\ n' на'; 'и поместите все в одну длинную строку. – alistaire
Спасибо за ваш комментарий. К сожалению, выполняется 'engine.eval (" print (\ "Hello \"); print (\ "World! \") ");' Только печатает "Hello". – Skifozoa