Home > Blockchain >  Complie multiple instances of SAME markdown into ONE pdf
Complie multiple instances of SAME markdown into ONE pdf

Time:05-28

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")
}
```
  •  Tags:  
  • r
  • Related