To pass data between Java and TIBCO Enterprise Runtime for R
One limitation of the TerrJava methods for evaluating expressions is they do not support sending data between Java and TIBCO Enterprise Runtime for R, except for a single string value returned from evaluateToString. Simple values can be included in the expression string sent to TIBCO Enterprise Runtime for R, and the string value returned from evaluateToString can include some data, but this is not reasonable for transferring large amounts of data.
The solution is to use methods for converting between TIBCO Enterprise Runtime for R data objects and Java TerrData objects:
public static void setVariable(String name, TerrData value) public static TerrData getVariable(String name) public static TerrData getVariable(String name, TerrData reuse)
- The first method converts a TerrData object into a TIBCO Enterprise Runtime for R data object, and assigns it to the specified global variable.
- The second method retrieves the value of a global variable, and converts it to a TerrData object.
- The third method retrieves a value, but also allows reusing the storage of an existing TerrData object, reducing Java object allocation.
TerrData is the superclass of several specific classes for representing particular types of TIBCO Enterprise Runtime for R data objects, including TerrDouble, TerrString, TerrFactor, TerrList, and TerrDataFrame. Here is some example code showing how to start an embedded engine, construct a TerrDataFrame object in Java, send it to TIBCO Enterprise Runtime for R, evaluate a linear model on the data and retrieve the coefficients of the model as another TerrData object.
TerrJava.startEngine();
TerrDataFrame df = new TerrDataFrame(new String[] { "x", "y" },
new TerrData[] {
new TerrDouble(new double[] { 1,2,3,4,5,6 }),
new TerrDouble(new double[] { 1,4,9,16,25,36 })
});
TerrJava.setVariable("df", df);
TerrJava.evaluateInteractive("df.mod <- lm(y~x, data=df)");
TerrJava.evaluateInteractive("df.coef <- df.mod$coefficients");
TerrData coef = TerrJava.getVariable("df.coef");
for (int i=0; i<coef.getLength(); i++) {
System.out.println(coef.names[i]+" : "+((TerrDouble)coef).data[i]);
}
// this prints:
// (Intercept) : -9.333333333333345
// x : 7.000000000000002
Before the development of the TerrData object and these methods for reading and writing variables, the best way to transfer data between Java and TIBCO Enterprise Runtime for R was to use the .JavaMethod function to call static Java methods that read or write values from static Java fields. However, this only supported reading and writing simple vectors of doubles, strings, and so on. Large and complex objects such as data.frames could be transferred by breaking them down into simple vectors that can be transferred via .JavaMethod.
This works, but the code is complex and unreliable and slow.
In one test, transferring a data frame with 40 columns of doubles as a TerrDataFrame was 100 times as fast as transferring the columns individually via .JavaMethod.