16.4 Child documents (*)
When you feel an R Markdown document is too long, you may consider splitting it into shorter documents, and include them as child documents of the main document via the chunk option child
. The child
option takes a character vector of paths to the child documents, e.g.,
```{r, child=c('one.Rmd', 'two.Rmd')}
```
Since knitr chunk options can take values from arbitrary R expressions, one application of the child
option is the conditional inclusion of a document. For example, if your report has an appendix containing technical details that your boss may not be interested in, you may use a variable to control whether this appendix is included in the report:
`BOSS_MODE` to `TRUE` if this report is to be read
Change
by the boss:
```{r, include=FALSE}
BOSS_MODE <- FALSE
```
Conditionally include the appendix:
```{r, child=if (!BOSS_MODE) 'appendix.Rmd'}
```
Or if you are writing a news report on a football game that has not taken place yet, you may include different child documents depending on the outcome, e.g., child = if (winner == 'brazil') 'brazil.Rmd' else 'germany.Rmd'
. Then as soon as the game (between Germany and Brazil) is finished, you can publish your report.
Another way to compile child documents is the function knitr::knit_child()
. You can call this function in an R code chunk or an inline R expression, e.g.,
```{r, echo=FALSE, results='asis'}
res <- knitr::knit_child('child.Rmd', quiet = TRUE)
cat(res, sep = '\n')
```
The function knit_child()
returns a character vector of the knitted output, which we can write back to the main document with cat()
and the chunk option results = 'asis'
.
You can even use a child document as a template, and call knit_child()
on it repeatedly with different parameters. In the example below, we run a regression using mpg
as the response variable and each of the rest of variables in the mtcars
data as the explanatory variable.
```{r, echo=FALSE, results='asis'}
res <- lapply(setdiff(names(mtcars), 'mpg'), function(x) {
knitr::knit_child(text = c(
'## Regression on "`r x`"',
'',
'```{r}',
'lm(mpg ~ ., data = mtcars[, c("mpg", x)])',
'```',
''
), envir = environment(), quiet = TRUE)
})
cat(unlist(res), sep = '\n')
```
To make the above example self-contained, we used the text
argument of knit_child()
instead of a file input to pass the R Markdown content to be knitted. You can certainly write the content to a file, and pass a path to knit_child()
instead. For example, you can save the content below to a file named template.Rmd
:
## Regression on "`r x`"
```{r}
lm(mpg ~ ., data = mtcars[, c("mpg", x)])
```
And knit the file instead:
<- lapply(setdiff(names(mtcars), 'mpg'), function(x) {
res ::knit_child(
knitr'template.Rmd', envir = environment(), quiet = TRUE
)
})cat(unlist(res), sep = '\n')