2014-07-09 4 views
0

Я пишу код Java, где я пытаюсь получить данные из PostgreSQL и выполнять простые вычисления на нем (вычисление медианы). Сначала я загружаю библиотеку RPostgreSQL из самого кода Java, а затем загружаю драйвер и устанавливаю соединение между R и PostgreSQL через Java. Но когда я пытаюсь сгореть команду запроса (который используется для получения запроса от PostgreSQL к R) через Java, то я получаю ошибку как:Ошибка при выполнении команд R в Java для доступа к данным из PostgreSQL и выполнения вычислений

Примечание: Эта ошибка RESOLVED.PLEASE СМОТРИТЕ НИЖЕ ДЛЯ CURRENT ERROR (Ошибка файла сценария)

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(); 
     } 
    } 
    } 
} 

Я не думаю, что есть какие-либо проблемы с Rserve связи, как для простого кода, как отображение версии R он становится выполнен правильно.

Также нет проблем с синтаксисом написания команд для R в PostgreSQL, например, с помощью dbSendQuery() или подобного, например, когда я использую их непосредственно из R, они работают отлично. Итак, проблема, которая, как мне кажется, заключается в том, чтобы писать то же самое в Java (соответствующий синтаксис для Java).

UPDATE 1: ERROR 2 (эта ошибка ПОСТАНОВИЛИ)

После принятия предложения от @ on_the_shores_of_linux_sea я изменил мой код немного, но теперь другая ошибка приходит как:

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 

Я не могу понять, почему возникает ошибка и как ее решить.

ВТОРИЧНЫЙ ВОПРОС: Это второстепенный вопрос, поскольку я также хочу знаете, что возможно, что я могу писать R-запросы или заявления в файле (специальный файл формата R или любой другой файл формата), а затем заставить Java читать файл и нажимать R-команды на R, чтобы их выполнить?

ОБНОВЛЕНИЕ 2: SCRIPT ОШИБКА ФАЙЛА

Метод 1 упомянутый ниже @on_the_shores_of_linux_sea теперь работает нормально. Я также пытаюсь сделать с помощью метода 2, но с некоторыми трудностями в управлении скриптом через Java. Код 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 ("попробовать (dbSendQuery (г, \" выберите colmn1 от предела host_brnd345633456_table1 10 \ "), бесшумный = TRUE)"); –

+0

Я чувствую, что вам не нужны котировки для dbSendQuery, попробуйте вышеуказанное изменение и проверьте, все ли работает нормально. –

+0

@on_the_shores_of_linux_sea Я сделал изменения, как вы предлагали, но теперь наступает другая ошибка. Я изменил свой код выше и также упомянул ошибку, которую я получаю. – user2966197

ответ

1

Как работает RENGINE, он подключается к сеансу Rserve через сокет и отправляет команды через eval или parseAndEval.R сессия не известно о каких-либо переменных, созданных в Java, так что если вы эти переменные в последующих Evals, он будет бросать ошибки

Есть два пути решения вашей проблемы

Метод 1 - назначение переменных внутри 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) 
} 

Java Code

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 как double'. Когда я использую обычные R-команды из консоли R, конечный результат отображается примерно так на консоли R '[1] 1178.30'. Почему это бросает ошибку, когда я использую те же команды через Java parseAndEval()? – user2966197

+0

, когда я печатаю res как 'asString()' вместо 'asDouble()', тогда он печатает ошибку, указанную как «Ошибка в медиане (ftch $ colmn): объект« ftch »не найден». Он не может найти ftch, хотя ftch определен на предыдущем шаге – user2966197

+0

Я отлаживал и замечал, что там, где я использую 'dBSendQuery()' не выдается ошибка, но когда я печатаю 'rs', то следующее выводится на выходную консоль' Ошибка в (function (classes, fdef, mtable): невозможно найти унаследованный метод для функции 'dbSendQuery' для подписи '' character ',' character '' '. Я думаю, что проблема начинается с этой строки и поэтому возникают проблемы в каждой команде после этого. Также я заметил в вашем коде, что в 'dbConnect()' у вас есть 'r <- try (dBConnect())', но в строках после этого у вас есть 'try (rs <-dBSendQuery())' Я попытался в обоих направлениях, но не успел – user2966197

 Смежные вопросы

  • Нет связанных вопросов^_^