What\'s the best way to call R functionality from within Java?
I\'m looking for a quick, easy and reliable way to make standard 2d scatter plots and histograms in R
I have found that forking R as a process, attaching to the process's stdin, stdout, and stderr streams, and sending R commands via the input stream to be quite effective. I use the filesystem to communicate between R and my Java process. This way, I can have multiple R processes running from different threads in Java and their environments do not conflict with each other.
FastR is a GraalVM based implementation of R. Embedding it in a JVM application is as simple as:
Context ctx = Context.newBuilder("R").allowAllAccess(true).build();
ctx.eval("R", "sum").execute(new int[] {1,2,3});
For your concrete example, this example plots a scatter plot using the lattice
R package, but the output is drawn into Graphics2D
object.
Context context = Context.newBuilder("R").allowAllAccess(true).build();
// This R function opens FastR graphics device passing it Graphics2D object,
// then it plots the graph and closes the device
String src =
"library(grid); library(lattice); " +
"function(graphics, width, height, x, y) { " +
" awt(width, height, graphics);" +
" print(xyplot(as.vector(x) ~ as.vector(y)));" +
" dev.off();" +
"}";
Value showPlot = context.eval("R", src);
// Create a BufferedImage to use for the plotting
BufferedImage image = new BufferedImage(WIDTH, HEIGHT, TYPE_INT_RGB);
Graphics2D graphics = (Graphics2D) image.getGraphics();
graphics.setBackground(new Color(255, 255, 255));
graphics.clearRect(0, 0, WIDTH, HEIGHT);
// Invoke R plotting code and pass it graphics object
double[] x = new double[] {1.,2.,3.,4.};
double[] y = new double[] {1.,2.,3.,4.};
showPlot.execute(graphics, WIDTH, HEIGHT, x, y);
There is also an example that shows the plots inside a Swing window.
You can find more details about FastR in this medium post: https://medium.com/graalvm/faster-r-with-fastr-4b8db0e0dceb
Use JRI: http://www.rforge.net/JRI/. It comes bundled with rJava, including some examples of usage.
A very simple example would be like this:
import java.io.*;
import java.awt.Frame;
import java.util.Enumeration;
import org.rosuda.JRI.Rengine;
import org.rosuda.JRI.REXP;
import org.rosuda.JRI.RVector;
import org.rosuda.JRI.RMainLoopCallbacks;
public class rJavaTest {
public static void main(String[] args) {
Rengine re=new Rengine(args, false, new TextConsole());
REXP x;
re.eval("print(1:10/3)");
System.out.println(x=re.eval("iris"));
RVector v = x.asVector();
if (v.getNames()!=null) {
System.out.println("has names:");
for (Enumeration e = v.getNames().elements() ; e.hasMoreElements() ;) {
System.out.println(e.nextElement());
}
}
if (true) {
System.out.println("Now the console is yours ... have fun");
re.startMainLoop();
} else {
re.end();
System.out.println("end");
}
}
}
There is something new called http://www.renjin.org/
One thing i like it over JRI
is deployment, While jri
required that your application users will download R, renjin
does not, and it uses only the JVM
to run.
Packages or libraries for R with Java
Call R from Java
Call Java from R