JRStat, a Java to R interface based on JRI

Overview

With JRStat it is possible to call R routines via the jstatcom Engine system. The low level code is build on rJava/JRI. The JRStat engine is a facade to JRI that uses the jstatcom Type system (JSCData) and that can be used in a way very similar to the other implemented engines via the Engine.call and Engine.load methods. Type conversions between R data objects and JSCData input and output arguments are done automatically whenever a meaningful conversion exists.

Documentation

The javadoc for all classes in the package com.jstatcom.engine.jrstat is quite verbose and contains all necessary information. A README is in the jrstat package, examples are in the jrstat unit tests and below.

Features

JRStat allows to:

  • load R packages and source files
  • call R methods from Java and get results back
  • stop running calculations
  • set special R type information via JSCData.setJSCDataProperty, see the javadoc of com.jstatcom.engine.jrstat.RArgProps:
    • R lists can be represented by the JSCMap datatype on the Java side
    • input arguments can be used with an optional parameter name property which are then interpreted as R named parameters
    • a JSCString can be interpreted as an R formula or expression
    • a JSCNArray can be interpreted as an R data frame, names can be set
    • output arguments can be retrieved from R return lists via their names or via a list key property
    • R console output is directed to a configurable log4j logger

Configuration

JRStat does not use any other native dlls than JRI and it requires the same environment variables to be set:

  • the path to the jri dll must be set via the -Djava.library.path VM argument
  • R_HOME must be set
  • (Mac) the above settings should suffice for a Mac
  • (Windows) the R bin directory must be in PATH
  • a README is provided with jrstat for more on Unix/Linux configuration

Code Examples

The following code examples are taken from the unittests for jrstat.

This code snipped loads a standard package (which is not used here) and a sourcefile from the jrstat subdirectory. Then a method is called and the results are retrieved back from an R list:

        final Engine rStat = EngineTypes.RSTAT.getEngine();
        rStat.load("boot", RStatLoadTypes.RPACKAGE);
        // load my own sourcefile, just as a demo
        rStat.load("ols.R", RStatLoadTypes.USERCODE);
        JSCData x = new JSCNArray("x", new double[] { 1, 2, 3, 4, 1, 2, 3 });
        JSCData y = new JSCNArray("y", UMatrix.rndu(7, 1));
        x.setJSCProperty(RArgProps.PARAM_NAME, "x");
        y.setJSCProperty(RArgProps.PARAM_NAME, "y");
        JSCData pvals = new JSCNArray("pvals");
        JSCNArray covarb = new JSCNArray("covarb");
        rStat.call("ols", new JSCData[] { x, y },
                new JSCData[] { pvals, covarb });
        

Now the lm method is used with a data frame and a formula, notice the use of RArgProps enums:

        JSCData dat = new JSCNArray("dat", UMatrix.rndu(50, 4));
        dat.setJSCProperty(RArgProps.PARAM_NAME, "data");
        dat.setJSCProperty(RArgProps.DFRAME_VARNAMES, new String[] { "a", "b",
                "c", "d" });
        JSCData expr = new JSCString("expr", "a~b + c + d");
        expr.setJSCProperty(RArgProps.AS_FORMULA, true);
        expr.setJSCProperty(RArgProps.PARAM_NAME, "formula");
        JSCInt qr = new JSCInt("qr", false);
        qr.setJSCProperty(RArgProps.PARAM_NAME, "qr");
        JSCNArray coeff = new JSCNArray("coeff");
        coeff.setJSCProperty(RArgProps.RLIST_KEY, "coefficients");
        JSCNArray res = new JSCNArray("residuals");
        rStat.call("lm", new JSCData[] { expr, dat, qr }, new JSCData[] {
                coeff, res });

        // alternatively with a JSCMap holding the estimation object
        JSCMap result = new JSCMap("result");
        rStat.call("lm", new JSCData[] { expr, dat, qr },
                new JSCData[] { result });
        System.out.println(result.display());

        

Plotting is also possible and very convenient, the package JGR is needed to show the plot panel in Java. Here a few plot options are used and "alpha" is interpreted as an R expression, however, it will only be visible if you export to PDF/EPS:

        rStat.load("JGR", RStatLoadTypes.RPACKAGE);
        JSCData y = new JSCNArray("dat", UMatrix.rndu(50, 1));
        JSCData lty = new JSCInt("lty", 3);
        lty.setJSCProperty(RArgProps.PARAM_NAME, "lty");
        rStat.call("par", new JSCData[] { lty }, null);
        // greek alpha is not shown in GD panel but if exported to PDF
        JSCData title = new JSCString("t", "alpha");
        title.setJSCProperty(RArgProps.PARAM_NAME, "main");
        title.setJSCProperty(RArgProps.AS_EXPR, true);
        JSCData type = new JSCString("type", "l");
        type.setJSCProperty(RArgProps.PARAM_NAME, "type");
        rStat.call("plot", new JSCData[] { title, y, type }, null);   

Just to show a 3D plot with a number of options:

        JSCNArray x1 = new JSCNArray("x", UMatrix.seqa(1, 1, 10));
        x1.setJSCProperty(RArgProps.PARAM_NAME, "x");
        JSCNArray y1 = new JSCNArray("y1", UMatrix.seqa(1, 1, 10));
        y1.setJSCProperty(RArgProps.PARAM_NAME, "y");
        JSCNArray z = new JSCNArray("z", UMatrix.rndu(10, 10));
        z.setValAt(Double.NaN, 8, 2); // test an NaN
        z.setJSCProperty(RArgProps.PARAM_NAME, "z");
        JSCData col = new JSCString("col", "lightblue");
        col.setJSCProperty(RArgProps.PARAM_NAME, "col");
        JSCData theta = new JSCInt("theta", 30);
        theta.setJSCProperty(RArgProps.PARAM_NAME, "theta");
        JSCData phi = new JSCInt("phi", 30);
        phi.setJSCProperty(RArgProps.PARAM_NAME, "phi");
        JSCData expand = new JSCNumber("expand", 0.7);
        expand.setJSCProperty(RArgProps.PARAM_NAME, "expand");
        rStat.call("JavaGD", null, null);
        rStat.call("persp",
                new JSCData[] { x1, y1, z, col, theta, phi, expand }, null);