问题描述
以下代码是针对我遇到的问题的非常简化的 MRE.我试图避免使用 R
模板包,例如 brew
,而只使用 knit_expand()
来实现我的目标.问题有两个方面:
The following code is a very simplified MRE for an issue I'm experiencing. I'm trying to avoid R
template packages, such as brew
, and only use knit_expand()
to achieve my goals. The issue is twofold:
- 不会解析生成的块(这在我的实际代码中不会发生,但会发生在 MRE 中)
- 代替 LaTeX
\includegraphics
,knitr
(或rmarkdown
,或pandoc
)生成用于插入的 RMarkdown 语法数字 (![]
).
- generated chunks don't get parsed (this is not happening in my real code, but happens in MRE)
- instead of LaTeX
\includegraphics
,knitr
(orrmarkdown
, orpandoc
) generates RMarkdown syntax for inserting figures (![]
).
关于前者,我有一种感觉,这可能与我对 get()
或其参数的错误使用有关.您的建议将不胜感激.MRE 如下('.Rmd' 文件):
In regard to the former, I have a feeling that it might be related to my incorrect use of get()
or its argument. Your advice would be very much appreciated. The MRE follows ('.Rmd' document):
---
title: "MRE: a dynamic chunk issue"
author: "Aleksandr Blekh"
output:
pdf_document:
fig_caption: yes
keep_tex: yes
highlight: NULL
---
```{r, echo=FALSE, include=FALSE}
library(knitr)
opts_knit$set(progress = F, verbose = F)
opts_chunk$set(comment=NA, warning=FALSE, message=FALSE, echo=FALSE, tidy=FALSE)
```
```{r Preparation, results='hide'}
g1 <- plot(cars)
g2 <- plot(iris$Sepal.Length)
myPlots <- list(g1, g2)
bcRefStr <- list("objType" = "fig",
"objs" = c("g1", "g2"),
"str" = "Plots \\ref{fig:g1} and \\ref{fig:g2}")
```
```{r DynamicChunk, include=FALSE}
chunkName <- "{{name}}"
chunkHeader <- paste0("```{r ", chunkName, ", ")
chunkOptions <- "include=TRUE, results='asis', fig.height=4, fig.width=4, fig.cap='{{name}}'"
chunkHeaderFull <- paste0(chunkHeader, chunkOptions, "}")
chunkBody <- "print(get('{{name}}'))"
latexFigEnvBegin <- "cat('\\\\begin{figure}')"
latexFigEnvEnd <- "cat('\\\\end{figure}')"
latexFigCenter <- "cat('\\\\centering')"
latexObjLabel <- paste0("cat('\\\\caption{\\\\ ", "{{name}}\\\\label{", bcRefStr$objType, ":{{name}}", "}}')")
chunkText <- c(chunkHeaderFull,
latexFigEnvBegin, latexFigCenter,
chunkBody,
latexObjLabel, latexFigEnvEnd,
"```", "\n")
figReportParts <- lapply(bcRefStr$objs, function (x) knit_expand(text = chunkText, name = x))
```
`r knit(text = unlist(figReportParts))`
推荐答案
最后,我找到了导致问题的原因.第一部分很简单.由于建议的简化,我已从 ggplot2
切换到标准的 R
图形函数.问题在于 plot()
似乎没有返回值/对象,所以这就是为什么在输出中看到的是 NULL,而不是图中.
Finally, I've figured out what was causing the issue. The first part was easy. Due to suggested simplification, I've switched from ggplot2
to standard R
graphics functions. The problem is that it appears that plot()
doesn't return a value/object, so that's why NULLs has been seen in the output, instead of plots.
第二部分有点棘手,但对相关问题的回答(https://stackoverflow.com/a/24087398/2872891) 阐明了情况.根据这些信息,我能够相应地修改我的 MRE,结果文档显示正确的内容(同样适用于生成的 LaTeX 源,它似乎已准备好进行交叉引用).
The second part was a bit more tricky, but an answer to a related question (https://stackoverflow.com/a/24087398/2872891) clarified the situation. Based on that information, I was able modify my MRE correspondingly and the resulting document appears with correct content (same applies to the generated LaTeX source, which seems to be ready for cross-referencing).
我正在考虑将此代码转换为更通用的函数,以便在我的项目中重用,如果时间允许的话[应该不会花很长时间](@Yihui,这对 knitr
有用吗?项目?).感谢所有花时间分析、帮助或只是阅读这个问题的人.我认为 knitr
的文档应该更清楚地说明与从 RMarkdown
源生成 PDF
文档相关的问题.我针对 MRE 的解决方案如下.
I'm thinking about converting this code into a more generic function for reuse across my project, if time will permit [shouldn't take long] (@Yihui, could this be useful for knitr
project?). Thanks to everyone who took time to analyze, help or just read this question. I think that knitr
's documentation should be more clear on issues, related to producing PDF
documents from RMarkdown
source. My solution for the MRE follows.
---
title: "MRE: a dynamic chunk issue"
author: "Aleksandr Blekh"
output:
pdf_document:
fig_caption: yes
keep_tex: yes
highlight: NULL
---
```{r, echo=FALSE, include=FALSE}
library(knitr)
library(ggplot2)
opts_knit$set(progress = F, verbose = F)
opts_chunk$set(comment=NA, warning=FALSE, message=FALSE, echo=FALSE, tidy=FALSE)
```
```{r Preparation, results='hide'}
library(ggplot2)
g1 <- qplot(mpg, wt, data=mtcars)
g2 <- qplot(mpg, hp, data=mtcars)
myPlots <- list(g1, g2)
bcRefStr <- list("objType" = "fig",
"objs" = c("g1", "g2"),
"str" = "Plots \\ref{fig:g1} and \\ref{fig:g2}")
```
```{r DynamicChunk, include=FALSE}
latexObjLabel <- paste0("{{name}}\\\\label{", bcRefStr$objType, ":{{name}}", "}")
chunkName <- "{{name}}"
chunkHeader <- paste0("```{r ", chunkName, ", ")
chunkOptions <- paste0("include=TRUE, results='asis', fig.height=4, fig.width=4, fig.cap='", latexObjLabel, "'")
chunkHeaderFull <- paste0(chunkHeader, chunkOptions, "}")
chunkBody <- "print(get('{{name}}'))"
chunkText <- c(chunkHeaderFull,
chunkBody,
"```", "\n")
figReportParts <- lapply(bcRefStr$objs, function (x) knit_expand(text = chunkText, name = x))
```
`r knit(text = unlist(figReportParts))`
这篇关于knitr 模板 - 动态块问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!