了解如何读取设备列表

| 我在打开设备列表时遇到一个相当烦人的问题,试图构造一个为列表保存大量图形的函数。假设我们有以下数据:
Alist <- list(
  X1 = data.frame(X=rnorm(10),Y=1:10),
  X2 = data.frame(X=rnorm(10),Y=1:10),
  X3 = data.frame(X=rnorm(10),Y=1:10)
)
和以下功能:
myPlotFunc <- function(x,save=F){
    fnames <- paste(names(x),\"pdf\",sep=\".\")
    for(i in 1:length(x)){
      if(save){
        pdf(fnames[i])
        on.exit(dev.off(),add=T)
      }
      plot(x[[i]])
    }
    fnames
  }
如果我运行
fnames <- myPlotFunc(Alist,save=T)
,一切正常,我得到3个pdf文件,名称为
X1.pdf
X3.pdf
。也就是说,如果没有打开图形窗口。如果存在,则不会关闭其中一个pdf,并且所有后续图都将添加到pdf中,直到我在控制台中显式调用
dev.off()
为止。像这样 :
plot(Alist[[1]])
fnames <- myPlotFunc(Alist,save=T)
myPlotFunc(Alist,save=F)

> dev.list()
pdf 
  4 
如果我加上
on.exit({print(dev.cur());dev.off()},add=T)
,我得到以下输出:
> fnames <- myPlotFunc(Alist,save=T)
pdf 
  5 
windows 
      2 
pdf 
  3 
因此,显然需要从下到上重新列出列表,以关闭它遇到的所有内容。因此,如果有打开的图形窗口,则是下一个“当前”设备。意味着倒数第二个打开的pdf连接将不再被dev.off()关闭,因为
on.exit
调用中将有一个短的链接。 我通过将函数更改为来解决此问题:
myPlotFunc <- function(x,save=F){
    fnames <- paste(names(x),\"pdf\",sep=\".\")
    devs <- NULL
    on.exit(for(i in devs) dev.off(i), add=T)
    for(i in 1:length(x)){
      if(save){
        pdf(fnames[i])
        devs <- c(devs,dev.cur())
      }
      plot(x[[i]])
    }
    fnames
  }
但这感觉很尴尬。有什么我想念的,还是更好的解决方法? 免责声明: 如果您不知道,请在运行第三个代码块后运行
dev.off()
。完成后,您可以通过运行easily12 easily轻松清理。     
已邀请:
如何使帮助函数执行一个绘图:
myPlotFunc <- function(x, save=FALSE) {
    fnames <- paste(names(x), \"pdf\", sep=\".\")
    plot_one <- function(xx, fname, save=save) {
        if (save) {
            pdf(fname)
            on.exit(dev.off())
        }
        plot(xx)
    }
    for (i in 1:length(x)) plot_one(x[[i]], fnames[i], save)

    fnames
}
    
一种可行的解决方案是使用
graphics.off()
而不是尝试关闭脚本打开的设备。如果这只是用户代码,那么在退出时是否关闭所有图形设备可能并不重要? 使用这种残酷的方法似乎有效:
myPlotFunc <- function(x,save = FALSE) {
    fnames <- paste(names(x),\"pdf\",sep=\".\")
    if(save)
        on.exit(graphics.off(),add = TRUE)
    for(i in 1:length(x)) {
      if(save) {
        pdf(fnames[i])
      }
      plot(x[[i]])
    }
    fnames
  }
一种替代方法是仅在调用
on.exit()
时列出所有设备,选择
pdf
并关闭它们。此函数实现了此功能,并且似乎具有所需的行为。
myPlotFunc2 <- function(x,save = FALSE) {
    fnames <- paste(names(x), \"pdf\", sep=\".\")
    if(save) {
        on.exit(foo <- lapply(dev.list()[grepl(\"pdf\", names(dev.list()))], 
                              dev.off),
                add = TRUE)
    }
    for(i in 1:length(x)) {
      if(save) {
        pdf(fnames[i])
      }
      plot(x[[i]])
    }
    fnames
  }
编号最低的设备似乎是R在调用
dev.off()
之后激活的设备,它将是您所描述的设置中的屏幕设备,因此是报告的行为。     

要回复问题请先登录注册