2016-10-07 5 views
0

Я экспериментировал с вызовом 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; 
    } 
} 
+0

Вы можете использовать точку с запятой для выполнения нескольких команд в одной строке в R, поэтому я подозреваю, что это сработает, если вы замените все '\ n' на'; 'и поместите все в одну длинную строку. – alistaire

+0

Спасибо за ваш комментарий. К сожалению, выполняется 'engine.eval (" print (\ "Hello \"); print (\ "World! \") ");' Только печатает "Hello". – Skifozoa

ответ

0

Я предлагаю использовать Rserve вместо rJava.

Я реализовал как в своей работе, так и решил свою проблему с помощью rServe.

Дополнительная реализация rserve находится в соединении.

Integrating R with Java

+0

Спасибо за предложение. Я определенно вижу преимущества использования rServe вместо rJava. Однако, в отношении этой конкретной проблемы, это больше избегает проблемы, чем ее исправление. Должен быть последовательный способ оценки скриптов, содержащих несколько операторов, распространяемых по нескольким строкам, нет? – Skifozoa

0

Что-то, что я делать с (но не самым элегантным решением) в данный момент заключается в следующем:

public REXP executeFromFile(Rengine engine, File file) throws Exception { 
     String fileName = file.getCanonicalPath().replace("\\", "\\\\"); 
     return execute(engine, "source(\""+fileName+"\")"); 
} 
Смежные вопросы