如何在使用ggsave和Rscript时阻止R创建空的Rplots.pdf文件

31

我有一个使用ggsave保存一些图形的R脚本。当我从命令行运行该脚本时,它不仅保存了我的图形,还保存了一个空的Rplots.pdf文件。如何防止R创建这个不必要的文件?

以下是一个可以复现此错误的示例脚本:

#!/usr/bin/env Rscript

# Code that creates unnecessary Rplots.pdf file
library(ggplot2)
my.data <- data.frame(x = 1:10, y = 1:10)
my.plot <- qplot(x, y, data = my.data)
ggsave('example.png', my.plot) 

以下所有运行脚本的方式都会创建不必要的文件:

Rscript script.R
Rscript --vanilla script.R
chmod a+x script.R
./script.R 

另外,当我在交互式会话中从源代码获取代码时,会打开一个不必要的空白R图形设备窗口。

此外,如果我使用以下更冗长的代码来代替ggsave,则不会出现这些问题:

#!/usr/bin/env Rscript

# Code that does NOT create unnecessary Rplots.pdf file
library(ggplot2)
my.data <- data.frame(x = 1:10, y = 1:10)
my.plot <- qplot(x, y, data = my.data)
png(file = 'example.png')
print(my.plot)
dev.off()

这是我的会话信息(无论是运行R脚本还是交互式操作,它都是相同的):

R version 3.0.1 (2013-05-16)
Platform: x86_64-pc-linux-gnu (64-bit)

locale:
 [1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C              
 [3] LC_TIME=en_US.UTF-8        LC_COLLATE=en_US.UTF-8    
 [5] LC_MONETARY=en_US.UTF-8    LC_MESSAGES=en_US.UTF-8   
 [7] LC_PAPER=C                 LC_NAME=C                 
 [9] LC_ADDRESS=C               LC_TELEPHONE=C            
[11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C       

attached base packages:
[1] methods   stats     graphics  grDevices utils     datasets  base     

other attached packages:
[1] ggplot2_0.9.3.1

loaded via a namespace (and not attached):
 [1] colorspace_1.2-2   dichromat_2.0-0    digest_0.6.3       grid_3.0.1        
 [5] gtable_0.1.2       labeling_0.1       MASS_7.3-26        munsell_0.4       
 [9] plyr_1.8           proto_0.3-10       RColorBrewer_1.0-5 reshape2_1.2.2    
[13] scales_0.2.3       stringr_0.6.2   
5年后的更新(2018年08月02日):这个问题时有时无。 ggplot2 2.2.1没有产生空文件,而ggplot2 3.0.0会产生,ggplot2团队目前正在努力解决此问题。有关开发历史,请参见ggplot2 Issues #1326, #2363, #2758#2787


如果在ggsave中指定高度和宽度,则似乎可以解决问题,但我承认我不知道原因...如果必须猜测,则是因为默认尺寸是"当前绘图窗口"的尺寸,需要存在才能测量它们。 - joran
我运行了ggsave,但它没有创建RPlots.pdf,只有example.pdf。在debug模式下,ggsave相对简单,你可以尝试一下并查看函数device正在调用什么。 - Señor O
我确实看到了这种行为,并且在交互式会话和使用RScript时指定高度和宽度参数似乎都可以解决它。 - joran
我可以确认这个。@joran,也许这值得一个错误报告? - Roland
@Roland,我想征求一些意见,看看是否有人认为这种行为是可取的。虽然我不喜欢它,但我并不确定没有人会更喜欢它。 - joran
我记得之前有类似这个问题的报告。你可能想要在SO上搜索,这是为ggplot2/plyr/reshape2问题维护的论坛,还可以查看github上的错误日志。 - IRTFM
2个回答

20

如果您查看ggsave中宽度和高度参数的默认值,您会发现它们是par(“din”)[1]par(“din”)[2]。如果您在控制台中运行此命令,您会发现它会打开一个图形窗口(如果没有打开的窗口存在)。

这种做法有一定道理,因为要获取设备的宽度/高度(以英寸为单位),您需要一个实际的设备。我想,如果没有设备处于打开状态,par(“din”)应该返回错误,如果是这样的话,Hadley肯定会以不同的方式编写ggsave

事实上,从 ?par 可以得知:

  

如果当前设备是空设备,则par将在查询/设置参数之前打开新设备。

因此,指定宽度/高度将防止意外打开设备。


谢谢,@joran!指定高度和宽度以避免par('din')调用确实解决了这个问题。 - John Blischak
这对我没有用(R 3.0.2; ggplot 0.9.3.1);我仍然会得到Rplots.pdf文件,除了我用filename指定的png(或pdf)文件之外。也许这与device参数有关? - knowah
@knowah 不确定;这个解决方案在我使用的 R 3.1.0 和 ggplot2 1.0.0 上仍然有效(我刚刚使用问题中的确切代码再次测试了它)。 - joran
12
这个解决方案对我没有用(R 3.1.0,ggplot2 1.0.0)。在一个R模块中,我把尺寸作为参数添加到所有的ggsave()调用中(PDF和SVG),但是还是生成了Rplots.pdf文件。我认为这可能之前是有效的,但我最近升级了我的服务器... - Aleksandr Blekh

3
另一个解决方案是使用包R.devices来抑制由ggsave打开的图形设备:
library(R.devices)
suppressGraphics(ggsave('example.png', my.plot))

请查看软件包作者的推文,了解另一个示例。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接