使用JRI在Java中获得与R控制台相同的输出

时间:2015-02-04 07:39:27

标签: r 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得到上面提到的输出?

2 个答案:

答案 0 :(得分:2)

这是一段可以工作的代码,这里我从对象的resultSeries(我转换为数据框)中提取字段mySeries.Open的第一个元素,它等于1,注意你不能将所有的resulSeries对象strait传递给Java,你需要将其分解。

package stackoverflow;

import org.rosuda.JRI.REXP;
import org.rosuda.JRI.Rengine;
/**
 *
 * @author yschellekens
 */
public class StackOverflow {      
   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

答案 1 :(得分:2)

我想出了以下解决方法。解决方案远非完美。

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攻击事件循环,在我的情况下它不需要(由于更复杂的错误处理)。