我正在使用带有Vaadin框架的Rcaller来制作一个从浏览器运行R-脚本的程序。其中一个功能应该是绘制绘图的能力。这本身并不是很困难,有一些方法可以用Rcaller做到这一点。然而,据我所见,所有这些方法都包括将生成的绘图从R保存到文件系统,然后用Java显示。
这是最不方便的,并且需要大量的时间和资源。我希望有一种方法可以将R的绘图作为流,并将其引导到Java,而不必在两者之间保存任何内容。
这有可能吗?
我查找了一个函数"grid.cap()"。它获取当前显示的绘图的快照,并以矩阵形式返回颜色。然后可以将这些值转换为RGB值。是否可以流式传输这些值,而不是绘图本身?这种方法至少有一个问题,它真的很慢。此外,我非常怀疑到底会返回什么,因为这取决于显示设备的状态。
这似乎不能用grid.cap()来完成,无论如何,这个问题可以通过一些配置来处理。我创建了一个这样的测试文件:
RCaller caller = new RCaller();
RCode code = new RCode();
caller.setRscriptExecutable("C:\Program Files\R\R-3.0.2\bin\Rscript.exe");
code.R_require("grid");
code.addRCode("dev.new(width=.5, height=.5)");
code.addRCode("grid.rect()");
code.addRCode("grid.text("hi")");
code.addRCode("cap <- grid.cap()");
code.addRCode("returns <- list(cap=cap)");
code.addRCode("dev.off()");
caller.setRCode(code);
caller.runAndReturnResult("returns");
int[] dims = caller.getParser().getDimensions("cap");
System.out.println("Names: " + caller.getParser().getNames());
System.out.println("Returned matrix dimensions: "+dims[0]+" - "+dims[1]);
这个代码产生这样的输出:
Names: []
Returned matrix dimensions: 0 - 0
手动运行生成的脚本会生成以下内容:
在网格中。调用(L_cap):光栅捕获对此设备不可用
Rscript无法检测到用于打印的正确设备,但是,当它直接在RGui中运行时,生成的RCaller脚本会正确运行并产生预期的输出。
> dim(returns$cap)
[1] 47 116
> head(returns$cap)
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,] "gray67" "gray67" "gray67" "gray67" "gray67" "gray67" "gray67" "gray67" "gray67" "gray67"
[2,] "gray67" "gray67" "gray67" "gray67" "gray67" "gray67" "gray67" "gray67" "gray67" "gray67"
在我看来,如果我错了,请原谅我,问题是为当前运行Rscript的设备之一找到图形设备或配置设置。