I'm using R Markdown to bulk generate parameterized pdf reports. I have no problem running each code chunk and no problem knitting single pdf. But when I run the lapply() function at the bottom, three (the "cut" variable in diamonds dataset has five categories) pdfs are generated successfully but I'm stuck at the fourth one, "Very Good". I get error messages instead:
WHAT DID I TRY:
I have re-installed R, RStudio, tinytex, and every package used in my code. I have pinpointed that the issue has something to do with the ggplot code chunk - hence, all five pdfs are generated successfully if I exclude that code chunk.
UPDATE:
CODE:
The following is everything I have in my current "testing_for_stackoverflow.Rmd" file that results in the fontspec error message:
---
output:
pdf_document:
latex_engine: xelatex
tables: true
graphics: yes
header-includes:
- \usepackage{booktabs}
- \usepackage{fontspec}
- \usepackage{graphicx}
- \usepackage{amsmath}
- \setmainfont{Times New Roman}
- \newcommand{\bcenter}{\begin{center}}
- \newcommand{\ecenter}{\end{center}}
params:
cut: "Very Good"
---
\fontsize{10}{12}
\selectfont
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = FALSE,
warning = FALSE,
message = FALSE,
fig.align = 'center',
include = TRUE,
tinytex.tlmgr_update = FALSE,
results='asis',
fig.dim = c(7, 2.5))
pacman::p_load(tidyverse)
```
## I'm using "diamonds" dataset and cut is my parameter
```{r}
filter(diamonds, cut == params$cut) %>%
ggplot(aes(color, price)) +
geom_boxplot()
```
```{r}
kableExtra::kable(head(filter(diamonds, cut == params$cut)))
```
Run this code in the console to produce several output files:
library(tidyverse)
lapply(unique(diamonds$cut), function(i) {
rmarkdown::render(input = "testing_for_stackoverflow.Rmd",
params = list(cut = i),
rmarkdown::pdf_document(),
output_dir = "out/",
output_file = paste0(i, ".pdf"))
})
The fourth document rendered (or rather not rendered) is the one containing a blank in the supposed intermediary and final filenames: Very Good...
. Guessing from the error message, the filename might be falsely interpreted as two separate instructions (undefined control sequence
).
Does replacing the blank solve the issue? One approach:
lapply(make.names(unique(diamonds$cut)), ...)
instead of:
lapply(unique(diamonds$cut), ...)
HOWEVER, make.names() will return "Very.Good" in the first argument of lapply() but since params = "Very Good", not data will be found in the rendering process. As a result, the pdf output of "Very Good" returns NA for all the data points being used.
So, the ultimate solution is to create a new variable using make.names(cut) and use the new variable as a parameter in the Rmd file for this parameterized report code to run (in a Windows system).