识别java中从RServe发送的字符串值或错误

时间:2016-10-06 18:33:31

标签: java r rserve

这是我的示例R文件:

# filename: sample.R
main <- function (){
  returnStringValue <- "ignore"
  return (returnStringValue)
}
main()

现在我尝试使用java:

在Rserve上使用该文件
import org.rosuda.REngine.REXP;
import org.rosuda.REngine.Rserve.RConnection;

public class RServeTest {

    static RConnection rcon;

    public static void main(String[] args) {
        try {

            String fileName = "sample.R";
            String filePath = "/filepath/";

            try {
                rcon = new RConnection();
            }
            catch(Exception e){
                System.out.println("Error Connecting: "+e);
            }

            String rCode = "source(\""+filePath+fileName+"\")";
            System.out.println("Rscript call on file: "+rCode);


            REXP r = rcon.parseAndEval("try(eval(parse(text="+rCode+")),silent=TRUE)");

            System.out.println("r object: "+r.asString());

            if (r.inherits("try-error")) 
                System.err.println("Error: "+r.asString());
            else 
                System.out.println("Executed R code successfully.");


        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }
}

这给了我以下错误:

Rscript call on file: source("/home/maverick/Documents/sem3/agent code/sample.R")
Error: Error in eval(expr, envir, enclos) : object 'ignore' not found

如何处理从R代码返回的字符串值,而不会影响被捕获的错误?

例如:

假设我的代码中有错误:

main <- function (){
  returnStringValue <- "ignore"

  # error
  var1+1

  return (returnStringValue)
}
main()

java代码应该记录:

Rscript call on file: source("/filepath/sample.R")
Error: Error in main() : object 'var1' not found

而不是记录:

org.rosuda.REngine.Rserve.RserveException: eval failed, request status: error code: 127
    at org.rosuda.REngine.Rserve.RConnection.eval(RConnection.java:233)
    at RServeTest.main(RServeTest.java:39)

2 个答案:

答案 0 :(得分:1)

可以通过从R返回json对象而不是字符串值来解决错误。以下是我解决此错误的方法:

源代码R文件的Java代码并运行main()函数:

import org.rosuda.REngine.REXP;
import org.rosuda.REngine.Rserve.RConnection;

public class RServeTest {

    static RConnection rcon;

    public static void main(String[] args) {
        try {

            String fileName = "sample.R";
            // Note: Change filename for testing different samples

            String filePath = "/filepath/";

            try {
                rcon = new RConnection();
            }
            catch(Exception e){
                System.out.println("Error Connecting: "+e);
            }

            String rCode = "source(\""+filePath+fileName+"\")";
            System.out.println("Rscript call on file: "+rCode);

            // Source file
            REXP r0 = rcon.parseAndEval("try(eval(parse(text="+rCode+")),silent=TRUE)");

            // Run main() function
            REXP r = rcon.parseAndEval("try(eval(parse(text=main())),silent=TRUE)");


            System.out.println("\n---------  with try error ------------");

            if (r.inherits("try-error")) 
                System.out.println("Error: "+r.asString());
            else 
                System.out.println("Executed R code successfully."+"r object: "+r.asString());

            System.out.println("\n---------  without try error ------------");

            System.out.println("R output :"+rcon.eval("main()").asString());


        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }
}

R代码示例1:

main <- function (){
  returnStringValue <- "ignore"
  return (returnStringValue)
}

结果:

Rscript call on file: source("/filepath/sample1.R")

---------  with try error ------------
Error: Error in eval(expr, envir, enclos) : object 'ignore' not found


---------  without try error ------------
R output :ignore

没有try-error方法给出了我们想要的返回字符串值,但是如果有错误,如下面的情况那样,它返回eval failed,只能使用{{1}来记录方法(请参见样本2)。

R代码示例2:

try-error

结果:

main <- function (){

  # error
  var1+1

  returnStringValue <- "ignore"
  return (returnStringValue)
}

可以通过从R返回json对象而不是字符串值来处理上述问题。以下是示例代码和结果:

R代码示例3:

Rscript call on file: source("/filepath/sample2.R")

---------  with try error ------------
Error: Error in main() : object 'var1' not found


---------  without try error ------------
org.rosuda.REngine.Rserve.RserveException: eval failed, request status: error code: 127
    at org.rosuda.REngine.Rserve.RConnection.eval(RConnection.java:233)
    at RServeTest.main(RServeTest.java:43)

结果:

require('rjson')
main <- function (){

  # error
  var1+1

  returnStringValue <- "ignore"
  returnJsonObject <- toJSON(returnStringValue)
  return (returnJsonObject)
}

R代码示例4:

Rscript call on file: source("/filepath/sample3.R")

---------  with try error ------------
Error: Error in main() : object 'var1' not found


---------  without try error ------------
org.rosuda.REngine.Rserve.RserveException: eval failed, request status: error code: 127
    at org.rosuda.REngine.Rserve.RConnection.eval(RConnection.java:233)
    at RServeTest.main(RServeTest.java:43)

结果:

require('rjson')
main <- function (){

  returnStringValue <- "ignore"
  returnJsonObject <- toJSON(returnStringValue)

  return (returnJsonObject)
}

因此,从样本3和4可以看出我们已经达到了我们想要的输出。

答案 1 :(得分:0)

我非常确定这一点,虽然我无法运行并验证下面写的准确性:

问题在于将rCode存储在变量text中,这使得REXP r成为一个赋值,而不是只返回一个字符串。尝试删除text=,您的代码应该可以正常工作。

如果上述情况有效,可以通过进一步的发展进行更新。