My data file includes a long list of case, one row per case. I want to produce a long PDF report, that would include one page per case, each page would contain the same table and graphs, but for a different case.
I understand I should have a 'child' markdown (one page), for example, childfile.Rmd
:
---
title: "case number `r params$case[1]`"
output: pdf_document
params:
case: [0,0,0,0,0,0,0]
---
```{r part1, echo=FALSE}
params$case[2:4]
```
```{r part2, echo=FALSE}
params$case[5:7]
```
and render it using a loop in a 'parent' markdown, for example, parentfile.Rmd
:
---
title: "all cases"
output: pdf_document
---
```{r parent, include=FALSE}
df = data.frame(number = c(1,2,3,4),
var1 = c(1,2,3,4),
var2 = c(1,2,3,4),
var3 = c(1,2,3,4),
var4 = c(1,2,3,4),
var5 = c(1,2,3,4),
var6 = c(1,2,3,4) )
for ( i in 1:4 ){
rmarkdown::render("childfile.Rmd",
params = list(case = as.vector(df[i,])))
}
```
However, this results in a blank pdf for the parent, and a second pdf for the chid, containg only the last case.
How can the complete set of child PDFs can be rendered into one PDF?
CodePudding user response:
I think there are two difficulties here. The first is that rmarkdown::render()
will compile the document by itself; to compile the child document within the parent, knitr::knit_child()
will do the trick. In the example below, I used the technique described in this answer to feed the appropriate case into each iteration of the child: by using a variable instead of parameters.
The second is that a LaTeX document, to my knowledge, can have only one title. So we can't give each child document its own title; but we can give each one its own heading (whose style can be easily customized if you want).
Child document
Note that the child document isn't a standalone markdown file; it's just enough for the material we want to render. Instead of referring to a parameter called case
, we refer to a variable of the same name.
# case `r unname(unlist(case[1]))`
```{r}
case[2:4]
```
```{r}
case[5:7]
```
\pagebreak
Parent document
The loop iterates over the first four rows of df
. For each row, it sets the variable case
(which the child document will need) and then uses knitr::knit_child()
to process the child. We send the knit output back into the parent document with cat()
; note also that this chunk crucially sets the results='asis'
option.
---
title: "all cases"
output: pdf_document
---
```{r setup, include=FALSE, echo=FALSE}
df = data.frame(number = c(1,2,3,4),
var1 = c(1,2,3,4),
var2 = c(1,2,3,4),
var3 = c(1,2,3,4),
var4 = c(1,2,3,4),
var5 = c(1,2,3,4),
var6 = c(1,2,3,4))
knitr::opts_chunk$set(echo=FALSE)
```
```{r parent, results='asis'}
for(i in 1:4) {
case = df[i,]
cat(knitr::knit_child("childfile.Rmd", envir = environment(), quiet = T))
cat("\n")
}
```