【问题标题】:JRI - How locate Errors in RJRI - 如何定位 R 中的错​​误
【发布时间】:2014-12-07 06:42:10
【问题描述】:

所以基本上,我使用的是 Java、JRI(Java 的 R)和 RJDBC(在 JRI 的帮助下),它们都运行得很好。 现在,我想让我的程序尽可能地万无一失。假设,字符串 SQL_command 是某种垃圾,并不是真正有效的 SQL 语句。那样的话……

    re.eval("sql_data <- dbGetQuery(conn, \"" + SQL_command + "\")");

...应该出错了。 我的想法是这样的:如果 R 命令失败,R 中会有某种输出。如果一切正确,则没有输出。但是我怎样才能捕捉到可能的输出呢?

请记住,我的问题更多是关于如何捕获无效的 R 语句,因此对于可能的解决方案的任何其他建议也表示赞赏。 R 输出不一定重要,但无论如何它可能很有趣。

提前致谢!

【问题讨论】:

  • 我不明白...什么样的捕获? re.capture.output() 不存在。如果您的意思是在 R 内部...并没有真正帮助。如何使用“last.warning”? “猫(last.warning)”?
  • 好的,这就是为什么它是评论而不是答案。只是一个建议。

标签: java mysql r jri rjdbc


【解决方案1】:

我建议直接在 R 中捕获由于 R 代码引起的(可能的)异常。因此,如果我怀疑某个命令可能会出错,我会在 R 中使用 try 函数。沿着这个行:

       REXP y = re.eval("sql_data <- try(dbGetQuery(conn, \"" + SQL_command + "\"),silent=TRUE)");
       REXP x = re.eval("class(sql_data)");
       if ((x.asString()).equals("try-error")) {
          System.out.println(y.asString());
          // do something to catch the exception
       } else {
         // do normal stuff
       }

这样你也可以显示R错误。

这里有一点可重现的(除了数据库凭据)代码,它首先尝试执行有效的查询语句,然后是无效的。

      import java.io.*;
      import org.rosuda.JRI.*;
      public class Prova {
         public static void main(String[] args) {
           String[] commands = {"a<-try(dbGetQuery(conn,'show tables'))","a<-try(dbGetQuery(conn,'SS'))"};
           Rengine re=new Rengine (new String [] {"--vanilla"}, false, null);
           re.eval("require(RMySQL)");
           re.eval("conn<-dbConnect(MySQL(),user='xxx',password='xxx',dbname='xxx')");
           for (int i=0;i<2;i++) {
             REXP y = re.eval(commands[i]);
             REXP x = re.eval("class(a)");
             if ((x.asString()).equals("try-error")) {
               System.out.println(y.asString());
             } else {
               System.out.println(x.asString());
             }
           }
           re.end();
         }
      }

输出:

   data.frame
   Error in mysqlExecStatement(conn, statement, ...) : 
     RS-DBI driver: (could not run statement: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'SS' at line 1)

【讨论】:

  • 我试过了,但是没有用。通过使用 re.eval() 命令创建一个对象,只要括号中的 R 命令失败,它就会停止执行它所做的任何事情。换句话说:REXP x = re.eval(SOME_WRONG_R_CODE);跳过所有内容。
  • 您能否准确提供您要提供给 R 的 SQL_command
  • sql_data
  • 我在getAttribute 之后忘记了asString()。我要编辑我的答案。让我看看它是否有效。
  • 它没有,因为在我将 re.eval 存储到 REXP 对象后它会跳过所有内容。但是,如果 re.eval 命令正确执行,则不会发生这种情况。奇怪...
【解决方案2】:

根据the documentation for the org.rosuda.JRI.Rengine.eval(String) method,如果出现问题,将返回null。该方法不会抛出任何类型的Exception,因此它似乎没有提供任何确定问题原因的方法。

org.rosuda.REngine.parseAndEval(String) method 确实抛出了几个 Exception 类型,REngineExceptionREXPMismatchException,这可能会提供更多的失败解释,但文档并不清楚究竟为什么以及何时会抛出这些。

因此,您可以做的最好的事情可能是检查 null 返回值。

【讨论】:

  • 我没有那个 parseAndEval() 方法。根据 Eclipse,re.parseAndEval(String) 不存在。
  • 请注意,parseAndEval 方法在不同包中的完全不同的类中(具有几乎完全相同的名称)。所以你的re 对象将无法调用该方法。
猜你喜欢
  • 2014-06-27
  • 2015-11-29
  • 2012-09-15
  • 2012-03-19
  • 1970-01-01
  • 2014-09-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多