Search code examples
javarrserve

How to get data.frame in Java using Rserve


I use Twitter anomaly detection algorithm in my project. For this purpose I use Rserve library to run R code in my Java application.

My Java code:

RConnection connection = new RConnection();
connection.voidEval("library(AnomalyDetection)");
connection.eval("res <- AnomalyDetectionTs(data.frame(/*list of timestamps*/,/*list of values*/), direction='both', plot=FALSE, longterm=TRUE)");

And, as a result, I got this output:

    $anoms
              timestamp    anoms
1   1980-09-25 16:05:00  21.3510
2   1980-09-29 06:40:00 193.1036
3   1980-09-29 21:44:00 148.1740

To get results now I'm using this not nice solution: connection.eval("write.csv(res[['anoms']],file='anom.csv')");

Then I open this file in Java and parse the results.

So, how to get the output results in Java using Rserve possibilities for data.frame structure?


Solution

  • Simply write the R command such that it returns the desired result back to Java:

    RList l = c.eval("AnomalyDetectionTs(data, direction='both',
                     plot=FALSE, longterm=TRUE)$anoms").asList();
    

    What you get is the data frame (as a list) with the two variables timestamp and anoms.

    However, AnomalyDetectionTs returns dates in a horribly annoying and inefficient format so you may want to actually return a more sane result which is easier to work with in Java, e.g.:

    RList l = c.eval("{ res <- AnomalyDetectionTs(data, direction='both', plot=FALSE,
                              longterm=TRUE)$anoms;
                      list(as.POSIXct(res$timestamp), res$anoms) }").asList();
    double ts[] = l.at(0).asDoubles();
    double anom[] = l.at(1).asDoubles();
    for (int i = 0; i < ts.length; i++)
        System.out.println(new java.util.Date((long)(ts[i]*1000.0)) + ": " + anom[i]);
    

    PS: the right place for Rserve questions is the stats-rosuda-devel mailing list which will give you answers much faster.