2014-07-09 1 views
0

저는 PostgreSQL에서 데이터를 가져 와서 (계산 중앙값) Java 코드를 작성하고 있습니다. 먼저 Java 코드 자체에서 RPostgreSQL 라이브러리를로드하고 드라이버를로드하고 Java를 통해 R과 PostgreSQL 간의 연결을 설정합니다. 하지만 Java를 통해 PostgreSQL에서 쿼리를 가져 오는 데 사용되는 쿼리 명령을 실행하려고하면 오류가 발생합니다.PostgreSQL에서 데이터에 액세스하고 계산을 수행하기 위해 Java에서 R 명령을 실행하는 중 오류가 발생했습니다.

참고 :이 오류는 해결됩니다. 현재 오류가 발생했습니다 (스크립트 파일 오류)

org.rosuda.REngine.REngineException: eval failed, request status: R parser: syntax error 
org.rosuda.REngine.Rserve.RConnection.parseAndEval(RConnection.java:454) 
org.rosuda.REngine.REngine.parseAndEval(REngine.java:108) 
Rtemp.main(Rtemp.java:40) 
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
java.lang.reflect.Method.invoke(Method.java:483) 
com.intellij.rt.execution.application.AppMain.main(AppMain.java:120) 

내 현재 코드는 다음과 같습니다

import org.rosuda.REngine.REXP; 
import org.rosuda.REngine.Rserve.*; 

public class Rtemp { 
    public static void main(String[] args) throws Exception { 
    RConnection c = null; 

    try { 
     c = new RConnection(); 

     //Loading RPostgreSQL library 
     REXP x = c.eval("library(RPostgreSQL)"); 

     //Loading PostgreSQL driver 
     REXP drv = c.eval("dbDriver(\"PostgreSQL\")"); 

     // Establishing connection 
     REXP r = c.parseAndEval("try(\"dbConnect(drv, host='localhost', port='5432',dbname='r1', user='postgres', password='pwd')\",silent=TRUE)"); 
     if (r.inherits("try-error")) System.err.println("Error: "+r.asString()); 
     else System.out.println("Success eval 1"); 


     REXP rs = c.parseAndEval("try(dbSendQuery(r,\"select colmn1 from host_brnd345633456_table1 limit 10 \"), silent=TRUE)"); 
     if (rs.inherits("try-error")) System.err.println("Error: "+rs.asString()); 
     else System.out.println("Success eval 2"); 



     REXP ftch = c.parseAndEval("try(ftch(rs,n=-1),silent=TRUE)"); 
     if (ftch.inherits("try-error")) System.err.println("Error: "+ftch.asString()); 
     else System.out.println("Success eval 3"); 

     REXP res = c.parseAndEval("try(median(ftch$colmn1),silent=TRUE)"); 
     if (res.inherits("try-error")) System.err.println("Error: "+res.asString()); 
     else { 
     System.out.println("Success eval 4"); 
     System.out.println(res.asDouble()); 
     } 
#The line 58 error mentioned below in the error section is coming at this line 
     System.out.println(res.asDouble()); 
     //System.out.println(x.asString()); 
     System.out.println("Library loaded successfully"); 
    } catch(Exception e) { 
     e.printStackTrace(); 
    } finally { 
     if (c != null) 
     try { 
      c.close(); 
     } 
    } 
    } 
} 

나는 그것을 실행지고 R 버전을 표시 같은 간단한 코드로 Rserve 연결에 문제가 있다고 생각하지 않는다 바르게.

dbSendQuery()와 비슷한 R에서 PostgreSQL 부분으로 명령을 작성하는 구문에도 문제가 없습니다. R에서 직접 사용하는 경우와 같이 완벽하게 작동합니다. 그래서, 내가 생각하는 문제는 자바 (자바에 해당하는 구문)에서 똑같이 쓰는 것입니다.

UPDATE 1 :

Success eval 1 
Error: Error in is(object, Cl) : 
    error in evaluating the argument 'conn' in selecting a method for function 'dbSendQuery': Error: object 'r' not found 


Error: Error in is(object, Cl) : 
    error in evaluating the argument 'res' in selecting a method for function 'fetch': Error: object 'rs' not found 


Error: Error in median(ftch$t31001400) : object 'ftch' not found 

org.rosuda.REngine.REXPMismatchException: attempt to access org.rosuda.REngine.REXPString as double 
    at org.rosuda.REngine.REXP.asDoubles(REXP.java:77) 
    at org.rosuda.REngine.REXP.asDouble(REXP.java:103) 
    at Rtemp.main(Rtemp.java:58) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:483) 
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120) 

Process finished with exit code 0 

: ERROR 2 (이 오류가 해결 될 때)

내 코드를 조금 수정했습니다하지만 지금은 다른 오류로오고있다 on_the_shores_of_linux_sea @로부터 제안을 복용 후 오류의 원인과 해결 방법을 파악할 수 없습니다.

두 번째 질문 : 내가 R 쿼리 나 문장을 파일 (특별한 R 형식 파일이나 다른 형식 파일)에 쓰고 Java가 파일을 읽고 R 명령을 R로 밀어 실행시킬 수 있다는 것을 알아?

UPDATE 2 스크립트 파일 ERROR

아래 이제 잘 작동 @on_the_shores_of_linux_sea 언급 한 방법. 또한 방법 2를 통해 수행하려고하지만 Java를 통해 스크립트를 관리하는 데 어려움을 겪고 있습니다. 내가 사용하고 자바 코드는 다음과 같습니다

public class Java_RScript { 

    public static void main(String[] args) throws Exception { 
     RConnection c = null; 
     try { 
      c = new RConnection(); 
      c.parseAndEval("try(source("script.R"),silent=TRUE)"); 
      REXP res = c.parseAndEval("try(\"do_operation()\", silent=TRUE)"); 
      System.out.println("Success:" + res.asDouble()); 
     } catch (Exception e) { 

      e.printStackTrace(); 

     } finally { 

      if (c != null) { 

       try { 

        c.close(); 

       } finally { 
       } 

      } 

     } 

    } 
} 

인쇄지고 출력 콘솔에 오류가있는 그대로 :

org.rosuda.REngine.REXPMismatchException: attempt to access org.rosuda.REngine.REXPString as double 

내 스크립트 파일의 구문은 다음과 같습니다

do_operation <- function() 
{ 
drv <- dbDriver("PostgreSQL") 
    r <- dbConnect(drv, host='localhost', port='1234',dbname='db', user='user1', password='pswd') 
    rs <-dbSendQuery(r,"select colmn1 from hostess_table limit 10") 
    ftch <- fetch(rs,n=-1) 
    res <- median(ftch$colmn1) 
    return(res) 
} 

내가 오류가 스크립트 파일에 있는지 아니면 Java 구문에 있는지 확실하지 않습니다.

+0

REXP의 RS = c.parseAndEval ")는) 침묵 = TRUE를"("(dbSendQuery (R 시도, \"host_brnd345633456_table1 제한 10 \에서 colmn1를 선택); –

+0

dbSendQuery에 대한 따옴표가 필요 없다고 생각하고 위의 변경을 시도하고 모든 것이 제대로 작동하는지 확인하십시오. –

+0

@on_the_shores_of_linux_sea 제안대로 변경했지만 다른 오류가 발생했습니다. 위의 코드를 수정했고 내가 얻고있는 오류에 대해서도 언급했습니다. – user2966197

답변

1

RENGINE의 작동 방식은 소켓을 통해 세션을 Rserve에 연결하고 eval 또는 parseAndEval을 통해 명령을 보냅니다.이후 evals에서 당신이 변수, 그것은 문제

방법 1 해결하는 방법은 두 가지가 있습니다

오류

발생합니다 그래서 만약 R 세션은 Java로 작성된 변수를 인식하지 못합니다 - 지정 변수는 내부 evals을

import org.rosuda.REngine.REXP; 
import org.rosuda.REngine.Rserve.*; 

public class Rtemp { 
public static void main(String[] args) throws Exception { 
RConnection c = null; 

try { 
    c = new RConnection(); 

    //Loading RPostgreSQL library 
    c.eval("library(RPostgreSQL)"); 
    //Loading PostgreSQL driver 
    c.eval("drv <- dbDriver(\"PostgreSQL\")"); 

    // Establishing connection 
    REXP r = c.parseAndEval("r <- try(\"dbConnect(drv, host='localhost', port='5432',dbname='r1', user='postgres', password='pwd')\",silent=TRUE)"); 
    if (r.inherits("try-error")) System.err.println("Error: "+r.asString()); 
    else System.out.println("Success eval 1"); 


    REXP rs = c.parseAndEval("try(rs <-dbSendQuery(r,\"select colmn1 from host_brnd345633456_table1 limit 10 \"), silent=TRUE)"); 
    if (rs.inherits("try-error")) System.err.println("Error: "+rs.asString()); 
    else System.out.println("Success eval 2"); 



    REXP ftch = c.parseAndEval("try(ftch <- ftch(rs,n=-1),silent=TRUE)"); 
    if (ftch.inherits("try-error")) System.err.println("Error: "+ftch.asString()); 
    else System.out.println("Success eval 3"); 

    REXP res = c.parseAndEval("try(res <- median(ftch$colmn1),silent=TRUE)"); 
    if (res.inherits("try-error")) System.err.println("Error: "+res.asString()); 
    else { 
    System.out.println("Success eval 4"); 
    System.out.println(res.asDouble()); 
    } 
    #The line 58 error mentioned below in the error section is coming at this line 
    System.out.println(res.asDouble()); 
    //System.out.println(x.asString()); 
    System.out.println("Library loaded successfully"); 
} catch(Exception e) { 
    e.printStackTrace(); 
} finally { 
    if (c != null) 
    try { 
     c.close(); 
    } 
} 

} }

방법 - 2 R 스크립트를 사용하여 코드

파일에서 파일을 소스 script.R :

require(PostgresSQL) 
do_operation <- function() 
{ 
    r <- dbConnect(drv, host='localhost', port='5432',dbname='r1', user='postgres', password='pwd')\",silent=TRUE) 
    rs <-dbSendQuery(r,\"select colmn1 from host_brnd345633456_table1 limit 10 
    ftch <- ftch(rs,n=-1) 
    res <- median(ftch$colmn1) 
    return(res) 
} 

자바 코드

c = new RConnection(); 
    c.eval("source('script.R')"); 
    double res = c.eval("do_operation()").asDouble(); 
+0

방법 1에서 제안한대로 변경했는데'REXP res'를'asDouble()'로 인쇄 할 때 여전히 하나의 오류가 있습니다.오고있는 오류는'org.rosuda.REngine.REXPMismatchException : org에 대한 액세스 시도입니다. .rosuda.REngine.REXPString as double'. R 콘솔에서 정상적인 R 명령을 사용할 때 최종 결과는 R 콘솔'[1] 1178.30'에서 이와 같이 표시됩니다. Java parseAndEval()을 통해 동일한 명령을 사용할 때 오류가 발생하는 이유는 무엇입니까? – user2966197

+0

'asDouble()'대신'asString()'으로 res를 인쇄 할 때 'Error in median (ftch $ colmn) : object'ftch 'not found'라는 오류를 출력합니다. 이전 단계에서 ftch가 정의되어 있어도 ftch를 찾을 수 없습니다. – user2966197

+0

디버깅을하고 'dBSendQuery()'를 사용하는 곳에서 오류가 발생하지 않았지만'rs '를 출력하면 출력 콘솔에' (function (classes, fdef, mtable)) : 서명 '문자', '문자' ''에 대해'dbSendQuery '함수의 상속 된 메소드를 찾을 수 없습니다.이 줄부터 문제가 발생한다고 생각합니다. 또한 당신의 코드에서'dbConnect()'에'r user2966197

관련 문제