将位图格式(例如PNG)的绘图写入标准输出

j_r*_*ker 4 plot r stdout

是否有可能让R将位图格式(例如PNG)的绘图写入标准输出?如果是这样,怎么样?

具体来说我想跑Rscript myscript.R | other_prog_that_reads_a_png_from_stdin.我意识到可以创建一个临时文件并使用它,但这很不方便,因为可能会同时运行此管道的许多副本,因此需要选择唯一文件名的方案并在之后删除它们.

到目前为止,我已尝试设置outf <- file("stdout")然后运行bitmap(file=outf, ...)或者png(filename=outf, ...),但是两者都抱怨('file' must be a non-empty character stringinvalid 'filename' argument分别),这与这些功能的官方文档一致.

由于我能够说服R的read.table()功能从标准输入读取,我希望有一种方法.我无法通过搜索找到任何相关内容[r] stdout plot,或者stdout"standard output"(用或不带双引号)代替的任何变体,和/或plot替换为png.

谢谢!

Kon*_*lph 5

不幸的是,{grDevices}(并暗示,{ggplot2})似乎从根本上不支持这一点.

解决此问题的明显方法是:让图形设备写入临时文件,然后将该临时文件读回R会话并将其写入stdout.

但这失败了,因为一方面,数据无法读入字符串:R中的字符串不支持嵌入的空字符(如果您尝试将获得诸如"不允许空字符"的错误).另一方面,readBin并且writeBin失败是因为writeBin断然拒绝写入连接到stdout的任何设备,这是在文本模式下(忽略了在POSIX系统上两者相同的事实).

这只能通过令人难以置信的hacky方式来规避,例如通过打开二进制管道来执行命令,例如cat:

dev_stdout = function (underlying_device = png, ...) {
    filename = tempfile()
    underlying_device(filename, ...)
    filename
}

dev_stdout_off = function (filename) {
    dev.off()
    on.exit(unlink(filename))
    fake_stdout = pipe('cat', 'wb')
    on.exit(close(fake_stdout), add = TRUE)
    writeBin(readBin(filename, 'raw', file.info(filename)$size), fake_stdout)
}
Run Code Online (Sandbox Code Playgroud)

要使用它:

tmp_dev = dev_stdout()
contour(volcano)
dev_stdout_off(tmp_dev)
Run Code Online (Sandbox Code Playgroud)

/dev/stdout存在的系统(大多数但不是所有POSIX系统)上,dev_stdout_off通过删除命令重定向可以略微简化该功能:

dev_stdout_off = function (filename) {
    dev.off()
    on.exit(unlink(filename))
    fake_stdout = file('/dev/stdout', 'wb')
    on.exit(close(fake_stdout), add = TRUE)
    writeBin(readBin(filename, 'raw', file.info(filename)$size), fake_stdout)
}
Run Code Online (Sandbox Code Playgroud)