【问题标题】:knitr: add to previous plot in new code chunkknitr:在新代码块中添加到先前的情节
【发布时间】:2018-05-24 00:09:18
【问题描述】:

我正在使用 R 的 knitr 包来生成将文本与嵌入式 R 绘图和输出相结合的 LaTeX 文档。

这样写是很常见的:

We plot y vs x in a scatter plot and add the least squares line:
<<scatterplot>>=
plot(x, y)
fit <- lm(y~x)
abline(fit)
@

效果很好。 (对于那些不熟悉knitrSweave 的人,这会在 LaTeX 逐字环境中回显代码和输出,并将完成的绘图作为图形添加到 LaTeX 文档中。)

但现在我想写更详细的逐行评论,例如:

First we plot y vs x with a scatterplot:
<<scatterplot>>=
plot(x, y)
@
Then we regress y on x and add the least squares line to the plot:
<<addline>>=
fit <- lm(y~x)
abline(fit)
@

问题是现在有两个knitr 代码块用于同一个情节。第二个代码块addline 失败,因为在第一个代码块scatterplot 中创建的图框对第二个代码块中的代码不可见。绘图窗口似乎不会从一个代码块持续到下一个代码块。

有什么方法可以告诉knit()plot() 创建的绘图窗口为第二个代码块保持活动状态?

如果这不可能,我还能如何在添加到现有绘图的代码行上实现 LaTeX 样式的注释?

一天后

我现在可以看到之前已经问过基本上相同的问题,请参阅: How to build a layered plot step by step using grid in knitr? 从 2013 年开始 Splitting a plot call over multiple chunks 从 2016 年开始。 2013 年的另一个问题也非常相似: How to add elements to a plot using a knitr chunk without original markdown output?

【问题讨论】:

  • 您希望最终文档的外观如何?您是否在文档中显示代码(即echo=TRUE)?只是你想展示和评论代码,然后渲染一次最终的情节吗?还是您想先显示没有 abline 的情节,然后再显示 abline 的情节?
  • @eipi10 我正在显示代码(echo=TRUE 和 eval=TRUE 设置为默认值)。我的意图是在文档中只包含一个完整的图,而不是在有或没有最小二乘线的情况下重复它。情节将处于浮动环境中。我实际上正在为期刊 (F1000Research) 写一篇代码工作流文章。

标签: r knitr


【解决方案1】:

您可以设置knitr::opts_knit$set(global.device = TRUE),这意味着所有代码块共享同一个全局图形设备。一个完整的例子:

\documentclass{article}

\begin{document}
<<setup, include=FALSE>>=
knitr::opts_knit$set(global.device = TRUE)
@

First we plot y vs x with a scatterplot:
<<scatterplot>>=
x = rnorm(10); y = rnorm(10)
plot(x, y)
@
Then we regression y and x and add the least square line to the plot:
<<addline>>=
fit <- lm(y~x)
abline(fit)
@

\end{document}

【讨论】:

  • 我才意识到我之前回答过类似的问题:stackoverflow.com/q/17502050/559676stackoverflow.com/q/37189068/559676
  • 谢谢,我已接受您的回答。但我在您的 knitr 网页或 R 包文档中找不到提到的 global.device 选项。我错过了它还是没有记录?我可以在一个文档期间多次重置global.device,还是必须为整个文档设置一次?
  • 它是无证的,仅适用于高级用户。您可以多次重置它。当您需要重置设备时,您只需在代码块中通过dev.off() 关闭全局设备。然后在下一个代码块中,会自动打开一个新的全局设备。
【解决方案2】:

您可以通过添加块选项eval=FALSE 来显示代码而不对其进行评估。如果您只想显示添加了回归线的绘图的最终版本,则使用eval=FALSE 作为第一个plot(x,y)

然后我们为回归线添加两个块:一个是渲染绘图所需的完整代码,但我们不想显示此代码,因为我们不想重复 plot(x,y) 调用。所以我们添加了第二个我们回显的块,以显示代码,但不评估。

---
output: pdf_document
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
```

```{r data}
set.seed(10)
x=rnorm(10)
y=rnorm(10)
```

First we plot y vs x with a scatterplot:

```{r scatterplot, eval=FALSE}
plot(x, y)
```

Then we regress y on x and add the least squares line to the plot:

```{r addline, eval=FALSE}
fit <- lm(y~x)
abline(fit)
```

```{r echo=FALSE}
plot(x,y)
fit <- lm(y~x)
abline(fit)
```

输出文档如下所示:

【讨论】:

  • 谢谢。这会生成我想要的文档,但它是一种解决方法,而不是我所追求的解决方案。我宁愿避免重复相同的代码两次(一次用于展示,一次用于评估)。
  • 是的,@YihuiXie 的回答肯定是要走的路。
猜你喜欢
  • 1970-01-01
  • 2014-01-27
  • 1970-01-01
  • 2019-07-06
  • 2018-12-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多