簡體   English   中英

在Java中執行R命令以從PostgreSQL訪問數據並進行計算時出錯

[英]Error while executing R commands in Java for accessing data from PostgreSQL and doing computation

我正在編寫Java代碼,試圖從PostgreSQL中獲取數據並對其進行簡單計算(計算中值)。 首先,我從Java代碼本身加載RPostgreSQL庫,然后加載驅動程序並通過Java在R和PostgreSQL之間建立連接。 但是,當我嘗試通過Java觸發查詢命令(用於從PostgreSQL向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();
        }
    }
  }
}

我認為Rserve連接沒有任何問題,因為對於簡單的代碼,例如顯示R的版本,它可以正確執行。

同樣,將R的命令寫到PostgreSQL部分(如dbSendQuery())的語法也沒有問題,就像當我直接從R內部直接使用它們時一樣,它們運行良好。 因此,我認為問題在於用Java編寫相同的內容(Java的相應語法)。

更新1:錯誤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:腳本文件錯誤

下面的@on_the_shores_of_linux_sea提到的方法1現在可以正常工作。 我也嘗試通過方法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語法中。

RENGINE的工作原理是,它通過套接字連接到Rserve會話,並通過eval或parseAndEval發送命令。 R會話不知道Java中創建的任何變量,因此如果您在后續評估中使用這些變量,則會引發錯誤

有兩種方法可以解決您的問題

方法1-在評估中分配變量

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腳本並從代碼中獲取文件

文件腳本

 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代碼

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM