【问题标题】:How to sequentially output partial (base r) plots in rmarkdown/knitr?如何在 rmarkdown/knitr 中顺序输出部分(基数 r)图?
【发布时间】:2019-12-04 16:15:55
【问题描述】:

假设我有以下 rmarkdown 代码:

---
title: "Untitled"
author: "Author"
date: "04/12/2019"
output: ioslides_presentation
---

## Slide title

```{r echo=FALSE}
plot(1:10, axes = FALSE, ty = "n")
axis(1)
## Next
axis(2)
## Next
points(1:10, 1:10)
```

在每个## Next 点上,我想输出绘图的当前状态,以便我可以按顺序显示绘图的某些部分。我的最终目标是在ioslides 演示文稿中创建后续幻灯片,其中包含顺序图,全部来自上面的代码(需要注意的是,理想情况下,我不希望后面的代码行能够影响前面的代码行,因为可能会发生以上)。

我希望它与我目前解决它的效果相同:

---
title: "Untitled"
author: "Author"
date: "04/12/2019"
output: ioslides_presentation
---

```{r setup, include=FALSE}

## Set up environment for running the code
env <- new.env()

## Source code to run, as a list of quotes

full_src <- list(
  quote({
    plot(1:10, axes = FALSE, ty = "n")
    axis(1)
    }),
  quote({
    axis(2)
    }),
  quote({
    points(1:10, 1:10)
    })
)

```

## Slide title

```{r echo=FALSE}
# Evaluate first set of lines
eval(full_src[[1]], envir = env)
# Reset environment so later code can't affect earlier code
rm(list = ls(envir = env), envir = env)
```

## Slide title

```{r echo=FALSE}
# Evaluate first and second set of lines
invisible(sapply(1:2, function(i) eval(full_src[[i]], envir = env)))
# Reset environment so later code can't affect earlier code
rm(list = ls(envir = env), envir = env)
```

## Slide title

```{r echo=FALSE}
# Evaluate all lines
invisible(sapply(1:3, function(i) eval(full_src[[i]], envir = env)))
```

输出的幻灯片如下所示:

但正如您所见,这很笨拙,而且不是很笼统。解决方案的重要特征是绘图的代码行尽可能靠近,并且只编写一次;理想情况下,我可以使用块选项/钩子来做到这一点。

最好的答案是保留回显添加到图表中的新代码行的能力(例如,## Next 标记之间的代码行),但仍会产生直到该点的整个图。

实现这一目标的最佳方法是什么?

编辑:另外,我希望能够将更改分组到一个绘图,而不仅仅是将每个更改输出到一个新绘图,所以fig.keep 将不起作用。

【问题讨论】:

  • Hmmmm...在文档中您可以设置块选项fig.keep = 'all',但是如果您希望在单独的幻灯片上输出,您可能需要单独的代码块...
  • 问题是fig.keep 会给我四个图,而不是三个,因为它保留了所有更改,而不仅仅是您想要的任意组(编辑以明确这一点)。
  • 你有没有看到this answer 回答过类似的问题?这个问题相当老了,所以我不知道它有多相关。
  • 好问题!有一个更好的方法可以做到这一点,但我刚刚在 knitr 中发现了一个错误。修复错误后,我会发布答案。
  • “我刚刚在 knitr 中发现了一个错误。我会在修复错误后发布答案。” ——谢一辉3小时前……低头看答案,3小时前回答——谢一辉。修复bug的速度真是神乎其神,一辉!加油!

标签: r r-markdown knitr


【解决方案1】:

块选项fig.keep 可以采用数字向量来索引图,因此您可以通过fig.keep = 2:4 选择最后三个图(或通过fig.keep = -1 删除第一个图)。

要将不同幻灯片上的图表分组,您可以动态添加幻灯片标题。您可以将cat('\n\n## Title\n\n') 与块选项results = 'asis' 一起使用,也可以与knitr::asis_output() 一起使用。

下面是一个完整的例子:

---
title: "Untitled"
author: "Author"
date: "04/12/2019"
output: ioslides_presentation
---

```{r, include=FALSE}
new_slide = function(title = '\n\n## Next\n\n') {
  knitr::asis_output(title)
}
```

## Slide title

```{r echo=FALSE, fig.keep=2:4}
plot(1:10, axes = FALSE, ty = "n")
axis(1)

new_slide()
axis(2)

new_slide()
points(1:10, 1:10)
```

请注意,当前版本的 knitr 中存在一个错误,即I just fixed on Github。现在你需要使用 Github 版本的 knitr

if (packageVersion('knitr') <= '1.26')
  remotes::install_github('yihui/knitr')

【讨论】:

  • 太棒了!我在这里的模板中包含了这个:github.com/richarddmorey/RcompileSlides/blob/master/inst/…,其中包括一个防止幻灯片编号增加的类。我还可以实现自动从第一张幻灯片的标题中获取标题的 javascript,这将避免每次都必须定义标题。但这正是我想要的;谢谢。
猜你喜欢
  • 1970-01-01
  • 2017-04-13
  • 2017-07-03
  • 1970-01-01
  • 1970-01-01
  • 2018-06-25
  • 2016-08-19
  • 2017-01-30
相关资源
最近更新 更多