如何让Rmarkdown包含来自源脚本打开的窗口的图?

时间:2016-12-10 16:58:23

标签: r knitr r-markdown

我在RStudio中使用Rmarkdown并包含在新图形窗口中打开的图表。如果直接在代码块中打开窗口,则处理的文档中包含 图。但是如果窗口是由源自单独的脚本打开的,则在Knitr处理期间会出现该图,但文档中包含。以下是演示的.Rmd脚本的完整最小示例:

---
title: "Rmarkdown graph inclusion"
---

# Make a simple plot:

```{r}
plot(0,0,main="Attempt 1")
```

Result of above: Plot is displayed during processing and is included in generated document.


# Make the plot in a separate graphics window:

```{r}
windows() # open new graphics window; x11() on Linux, MacOS
plot(0,0,main="Attempt 2")
```

Result of above: Plot is displayed during processing and is included in generated document.

# Make the plot in a separate graphics window called from another script:

```{r}
writeLines( "windows() ; plot(0,0,main='From File')" ,
            con="openWindowScript.R" )
source("openWindowScript.R")
```

Result of above: Plot **is** displayed during Knitr processing but is **NOT** included in the generated document. *Why not?*

我搜索了stackoverflow和其他地方的答案,但没有找到答案。提前感谢您的答案或指示!

2 个答案:

答案 0 :(得分:2)

如果在dev.print()调用后添加source,则应打印当前设备(在您的情况下应该是源设备)。然后由knit捕获并包含在文档中。所以,块应该是这样的:

```{r}
writeLines( "windows() ; plot(0,0,main='From File')" ,
            con="openWindowScript.R" )
source("openWindowScript.R")

dev.print()
```

我在Linux上进行了测试,它使用X11打开设备并打印它,但文档似乎暗示它应该在Windows上运行相同(只要Windows dev.print的特定版本是正确安装,默认情况下应该这样。)

如果dev.print在交互式运行时导致问题(只是令人讨厌或导致崩溃),您可以通过检查编织文件的名称来阻止它在编织文档外运行。这在交互式运行时返回NULL,因此可以用作if中的条件来阻止在编织之外执行。

使用有关此错误的注释中的示例,代码块变为:

```{r echo=1:2}
writeLines( "windows() ; plot(0,0,main='Ta-Da!')" ,
            con="theScript.R" )
source("theScript.R")

if(!is.null(knitr::current_input())){
  deviceInfo <- dev.print()  
}
```

另一种方法是覆盖windows()(和/或x11)的行为。在Rmd文档的顶部,添加

x11 <- windows <- function(...){invisible(NULL)}

哪个应该捕获对windowsx11的所有调用,并且基本上忽略它们(...确保您不应该得到“未使用的参数”错误)。如果您使用这些调用来设置尺寸和/或宽高比,则需要使用fig.widthfig.height。这可能会破坏您实际上想要 x11 / windows行为的其他内容,但使用grDevices::x11(或类似windows)可以获得正确的功能。所以,如果您处于紧张状态,并且愿意放弃首先使用windows的原因,那么这应该可行。

答案 1 :(得分:1)

代码遇到两个不同的问题。一个是openWindowScript.R中的代码,另一个是该文件如何包含在主文档中。

openWindowScript.R中的代码在直接用作块代码时甚至不会产生可见的图:

```{r}
windows(); plot(0,0,main='From File')
```

我认为这是由于顶级表达式和其他代码(例如here所提到的)之间的差异,但我不确定细节。 产生可见图的内容如下:

```{r}
windows()
plot(0,0,main='From File')
```

因此,在外部文件中使用此代码,我们如何将其包含在文档中? {em>不由source - 外部文件,大概是因为那时绘图命令再次不是顶级表达式。虽然Mark Peterson已经提供nice workaround,但我想建议更多knitr惯用解决方案:使用code option将代码注入一个块:

```{r}
writeLines( "windows() \n plot(0,0,main='From File')" ,
            con="openWindowScript.R" )
```

```{r, code = readLines("openWindowScript.R")}
```