使用 JRI 在 Java 中获得与 R 控制台相同的输出
Get same output as R console in Java using JRI
当我在R控制台中直接输入以下命令时
library("xts")
mySeries <- xts(c(1.0, 2.0, 3.0, 5.0, 6.0), order.by=c(ISOdatetime(2001, 1, 1, 0, 0, 0), ISOdatetime(2001, 1, 2, 0, 0, 0), ISOdatetime(2001, 1, 3, 0, 0, 0), ISOdatetime(2001, 1, 4, 0, 0, 0), ISOdatetime(2001, 1, 5, 0, 0, 0)))
resultingSeries <- to.monthly(mySeries)
resultingSeries
我会得到这样的输出
mySeries.Open mySeries.High mySeries.Low mySeries.Close
Jan 2001 1 6 1 6
当我查看属性时,我看到以下输出
attributes(resultingSeries)
$dim
[1] 1 4
$dimnames
$dimnames[[1]]
NULL
$dimnames[[2]]
[1] "mySeries.Open" "mySeries.High" "mySeries.Low" "mySeries.Close"
$index
[1] 978307200
attr(,"tclass")
[1] "yearmon"
$tclass
[1] "POSIXct" "POSIXt"
$tzone
[1] ""
$class
[1] "xts" "zoo"
$.indexCLASS
[1] "yearmon"
这与我在 Java 中得到的相同。我想知道魔术发生在哪里,以便我看到我在 R 中获得的漂亮输出。我无权访问事件循环,因为我使用的是这样的 JRI(因为,这是推荐的方式并简化了错误处理):
REngine engine = REngine.engineForClass("org.rosuda.REngine.JRI.JRIEngine");
REXP result = engine.parseAndEval(...)
/编辑
在 Java 中,我按如下方式执行上面的每个命令:
REXP result = engine.parseAndEval("resultingSeries") // or any other command
我得到的是
org.rosuda.REngine.REXPDouble@4ac66122+[12]
有效负载加倍:1, 6, 1, 6
属性与上面指定的相同。
现在 R 做了一些魔术来显示上面的输出。有没有一种方法可以获得相同的输出而无需自己手动创建它? R 得到上述输出的实现存储在哪里?
这是一段可以工作的代码,这里我从对象 resultingSeries(我转换为数据框)中提取字段 mySeries.Open 的第一个元素,它等于 1,请注意您不能将所有 resultingSeries 对象 strait 传递到 Java,您需要将其分解。
package Whosebug;
import org.rosuda.JRI.REXP;
import org.rosuda.JRI.Rengine;
/**
*
* @author yschellekens
*/
public class Whosebug {
public static void main(String[] args) throws Exception {
String[] Rargs = {"--vanilla"};
Rengine rengine = new Rengine( Rargs, false, null);
rengine.eval("library('xts')");
rengine.eval("mySeries <- xts(c(1.0, 2.0, 3.0, 5.0, 6.0), order.by=c(ISOdatetime(2001, 1, 1, 0, 0, 0), ISOdatetime(2001, 1, 2, 0, 0, 0), ISOdatetime(2001, 1, 3, 0, 0, 0), ISOdatetime(2001, 1, 4, 0, 0, 0), ISOdatetime(2001, 1, 5, 0, 0, 0)))");
rengine.eval("resultingSeries <- to.monthly(mySeries)");
rengine.eval("resultingSeries<-as.data.frame(resultingSeries)");
REXP result= rengine.eval("resultingSeries$mySeries.Open");
System.out.println("Greeting from R: "+result.asDouble());
}
}
并且 Java 输出:
run:
Greeting from R: 1.0
我找到了以下解决方法。解决方案远非完美。
R 提供了一个命令来将其控制台输出保存为字符向量。
capture.output( {command} )
我们可以使用
访问输出
REXPString s = rengine.parseAndEval("capture.output( to.monthly(mySeries))")
String[] output = result.asStrings()
变量输出将包含所有输出行
[0] mySeries.Open mySeries.High mySeries.Low mySeries.Close
[1]Jan 2001 1 6 1 6
或者,您可以使用 JRIEngine 并将自己攻击到事件循环,这在我的情况下是不需要的(由于更复杂的错误处理)。
当我在R控制台中直接输入以下命令时
library("xts")
mySeries <- xts(c(1.0, 2.0, 3.0, 5.0, 6.0), order.by=c(ISOdatetime(2001, 1, 1, 0, 0, 0), ISOdatetime(2001, 1, 2, 0, 0, 0), ISOdatetime(2001, 1, 3, 0, 0, 0), ISOdatetime(2001, 1, 4, 0, 0, 0), ISOdatetime(2001, 1, 5, 0, 0, 0)))
resultingSeries <- to.monthly(mySeries)
resultingSeries
我会得到这样的输出
mySeries.Open mySeries.High mySeries.Low mySeries.Close
Jan 2001 1 6 1 6
当我查看属性时,我看到以下输出
attributes(resultingSeries)
$dim
[1] 1 4
$dimnames
$dimnames[[1]]
NULL
$dimnames[[2]]
[1] "mySeries.Open" "mySeries.High" "mySeries.Low" "mySeries.Close"
$index
[1] 978307200
attr(,"tclass")
[1] "yearmon"
$tclass
[1] "POSIXct" "POSIXt"
$tzone
[1] ""
$class
[1] "xts" "zoo"
$.indexCLASS
[1] "yearmon"
这与我在 Java 中得到的相同。我想知道魔术发生在哪里,以便我看到我在 R 中获得的漂亮输出。我无权访问事件循环,因为我使用的是这样的 JRI(因为,这是推荐的方式并简化了错误处理):
REngine engine = REngine.engineForClass("org.rosuda.REngine.JRI.JRIEngine");
REXP result = engine.parseAndEval(...)
/编辑 在 Java 中,我按如下方式执行上面的每个命令:
REXP result = engine.parseAndEval("resultingSeries") // or any other command
我得到的是
org.rosuda.REngine.REXPDouble@4ac66122+[12]
有效负载加倍:1, 6, 1, 6 属性与上面指定的相同。
现在 R 做了一些魔术来显示上面的输出。有没有一种方法可以获得相同的输出而无需自己手动创建它? R 得到上述输出的实现存储在哪里?
这是一段可以工作的代码,这里我从对象 resultingSeries(我转换为数据框)中提取字段 mySeries.Open 的第一个元素,它等于 1,请注意您不能将所有 resultingSeries 对象 strait 传递到 Java,您需要将其分解。
package Whosebug;
import org.rosuda.JRI.REXP;
import org.rosuda.JRI.Rengine;
/**
*
* @author yschellekens
*/
public class Whosebug {
public static void main(String[] args) throws Exception {
String[] Rargs = {"--vanilla"};
Rengine rengine = new Rengine( Rargs, false, null);
rengine.eval("library('xts')");
rengine.eval("mySeries <- xts(c(1.0, 2.0, 3.0, 5.0, 6.0), order.by=c(ISOdatetime(2001, 1, 1, 0, 0, 0), ISOdatetime(2001, 1, 2, 0, 0, 0), ISOdatetime(2001, 1, 3, 0, 0, 0), ISOdatetime(2001, 1, 4, 0, 0, 0), ISOdatetime(2001, 1, 5, 0, 0, 0)))");
rengine.eval("resultingSeries <- to.monthly(mySeries)");
rengine.eval("resultingSeries<-as.data.frame(resultingSeries)");
REXP result= rengine.eval("resultingSeries$mySeries.Open");
System.out.println("Greeting from R: "+result.asDouble());
}
}
并且 Java 输出:
run:
Greeting from R: 1.0
我找到了以下解决方法。解决方案远非完美。
R 提供了一个命令来将其控制台输出保存为字符向量。
capture.output( {command} )
我们可以使用
访问输出REXPString s = rengine.parseAndEval("capture.output( to.monthly(mySeries))")
String[] output = result.asStrings()
变量输出将包含所有输出行
[0] mySeries.Open mySeries.High mySeries.Low mySeries.Close
[1]Jan 2001 1 6 1 6
或者,您可以使用 JRIEngine 并将自己攻击到事件循环,这在我的情况下是不需要的(由于更复杂的错误处理)。