我正在编写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语法中。
答案 0 :(得分:1)
RENGINE如何工作,它通过套接字连接到Rserve会话,并通过eval或parseAndEval发送命令。 R session不知道在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脚本并从代码
中获取文件file 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代码
c = new RConnection();
c.eval("source('script.R')");
double res = c.eval("do_operation()").asDouble();