Search code examples
rjri

Get same output as R console in Java using JRI


When I enter the following commands directly into the R console

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 

I will get an output like this

             mySeries.Open mySeries.High mySeries.Low mySeries.Close
Jan 2001             1             6            1              6

When I look into the attributes, I see the following output

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"

This is the same I get in Java. I'm wondering where the magic happens so that I see the nice output I get in R. I have no access to the event loop, since I'm using JRI like this (since, it's the recommended way and simplifies error handling):

REngine engine = REngine.engineForClass("org.rosuda.REngine.JRI.JRIEngine");
REXP result = engine.parseAndEval(...)

/edit In Java I execute each command from above as follows:

REXP result = engine.parseAndEval("resultingSeries") // or any other command

What I get is

org.rosuda.REngine.REXPDouble@4ac66122+[12]

The payload being doubles: 1, 6, 1, 6 The attributes are the same as specified above.

Now R does some magic to display the output above. Is there a way I can get the same output without having to create it manually by myself? Where's the implementation stored, that R gets the above mentioned output?


Solution

  • I figured out the following workaround. The solution is far from perfect.

    R offers a command to save its console output as characters vector.

    capture.output( {command} )
    

    We can access the output using

    REXPString s = rengine.parseAndEval("capture.output( to.monthly(mySeries))")
    String[] output = result.asStrings()
    

    The variable output will contain all output lines

    [0]             mySeries.Open mySeries.High mySeries.Low mySeries.Close
    [1]Jan 2001             1             6            1              6
    

    Alternatively you coud use JRIEngine and attack yourself to the event loop, which it did not want in my case (due to the more complicated error handling).