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

Identifying string values or error sent from RServe in java

这是我的示例 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)

我很确定这一点,虽然我不能运行验证下面所写内容的准确性:

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

如果以上方法有效,请更新进一步的开发。

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

Java 代码到源 R 文件和 运行 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

Without try-error 方法给了我们想要的 return 字符串值,但是如果出现错误,如下例所示,它 returns eval failed只能使用 try-error 方法记录(请参阅示例 2)。


R 代码示例 2:

main <- function (){

  # error
  var1+1

  returnStringValue <- "ignore"
  return (returnStringValue)
}

结果:

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)

上述问题可以通过从 R returning 一个 json 对象而不是字符串值来解决。以下是示例代码和结果:

R 代码示例 3:

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

  # error
  var1+1

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

结果:

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)

R代码示例4:

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

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

  return (returnJsonObject)
}

结果:

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

---------  with try error ------------
Executed R code successfully.r object: ignore

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

因此,从示例 3 和 4 您可以看到我们已经实现了我们想要的输出。