问题
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:
- 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 (![]
).
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))`
回答1:
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.
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).
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))`
来源:https://stackoverflow.com/questions/26883864/knitr-templating-dynamic-chunks-issue