是否可以让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 string
和invalid 'filename' argument
),与这些功能的官方文档一致。
由于我能够说服R的read.table()
函数从标准输入中读取内容,所以我希望有办法。我无法通过搜索[r] stdout plot
或在stdout
中将"standard output"
替换为plot
的任何变体形式(带或不带双引号)和/或png
替换为{{1}}。
谢谢!
答案 0 :(得分:5)
不幸的是,{grDevices}(并暗示{ggplot2})似乎从根本上不支持这一点。
解决此问题的明显方法是:让图形设备写入临时文件,然后将该临时文件读回到R会话并将其写入stdout。
但是这失败了,因为,一方面,数据不能读入字符串:R中的字符串不支持嵌入的空字符(如果尝试,则会出现诸如“不允许使用空字符”的错误) )。另一方面,readBin
和writeBin
失败是因为writeBin
断然拒绝写入连接到stdout的任何设备,该设备处于文本模式(忽略在POSIX系统上,两者是相同的事实。
只能以令人难以置信的hacky方式来规避,例如by opening a binary pipe to a command such as 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)
}
要使用它:
tmp_dev = dev_stdout()
contour(volcano)
dev_stdout_off(tmp_dev)
在存在/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)
}
答案 1 :(得分:1)
这可能不是一个完整的答案,但这是我所能得到的最好的答案:您可以使用stdout()
命令打开连接吗?我知道png()
会将输出设备更改为文件连接,但这不是您想要的,因此将png
替换为stdout
可能会起作用。但是,我对标准输出的了解还不足以检验这一理论。
help page建议此连接可能是纯文本的。在这种情况下,一种解决方案可能是生成一个随机字符串以用作文件名,然后通过stdout
传递文件名,以便管道中的下一步知道在哪里可以找到文件。