0

I am writing a Java code where in I am trying to get the data from PostgreSQL and doing simple computation on it(calculating median). First I am loading the RPostgreSQL library from Java code itself and then loading the driver and establishing the connection between R and PostgreSQL through Java. But when I am trying to fire a query command(which is used to get query from PostgreSQL to R) through Java then I am getting error as:

NOTE:THIS ERROR IS RESOLVED.PLEASE LOOK BELOW FOR CURRENT ERROR(Script File 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)

My current code is :

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

I don't think that there is any problem with Rserve connection as for simple code like displaying version of R it is getting executed correctly.

Also there is no problem with the syntax of writing commands for R to PostgreSQL part like the dbSendQuery() or similar as when I using them directly from within R they are working perfectly fine. So, the problem that I think is in writing the same in Java(corresponding syntax for Java).

UPDATE 1: ERROR 2 (THIS ERROR IS RESOLVED)

After taking suggestion from @ on_the_shores_of_linux_sea I have modified my code a bit but now a different error is coming as:

    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

I am not able to figure out why the error is and how to resolve it

SECONDARY QUESTION: This a secondary question as I also want to know that is it possible that I can write the R queries or statements in a file(a special R format file or any other format file) and then make Java read the file and push the R commands into R so as to execute them?

UPDATE 2: SCRIPT FILE ERROR

The method 1 mentioned by @on_the_shores_of_linux_sea below is working fine now. I am also trying to do through method 2 but having some difficulties in managing script through Java. The Java code that I am using is:

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 {
                }

            }

        }

    }
}

The error on output console that is getting printed is as:

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

My script file syntax is:

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

I am not sure whether the error is in script file or my Java syntax.

4

1 回答 1

1

RENGINE 的工作原理是,它通过套接字连接到 Rserve 会话并通过 eval 或 parseAndEval 发送命令。R会话不知道Java中创建的任何变量,因此如果您在后续评估中使用这些变量,它将引发错误

有两种方法可以解决您的问题

方法 1 - 在 eval 中分配变量

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 脚本并从代码中获取文件

文件脚本.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();
于 2014-07-11T04:15:52.067 回答