Many models, many plots, many pages!

A quick post showing a cool {knitr} trick you can use when creating a pdf with many plots and many pages.

Harry Fisher https://hfshr.xyz
01-29-2021

I wanted to share a cool knitr trick I recently discovered thanks to this excellent SO post.

The problem

The solution

For a quick demonstration, lets use the survival::verteran dataset. We want to fit a survival model for each celltype and use ggsurvplot to create a survival curve for each model. Finally we want to print out each of the plots on a new page in a pdf document.

library(tidyverse)
library(survival)
library(survminer)

# fit model for each celltype

by_celltype <- veteran %>% 
  nest_by(celltype) %>% 
  mutate(model = list(survfit(Surv(time, status) ~ trt, data = data)),
         plot = list(ggsurvplot(model, data = data)),
         name = str_glue("Survival curve by treatmeant for celltype: {celltype}"))

If you haven’t seen nest_by in action before, I’d highly recommend checking out this dplyr article.

Next we extract the list-column by_celltype$plot as a list, and give each element the name that was created using str_glue in the previous step.

all_plots <- as.list(by_celltype$plot)

names(all_plots) <- by_celltype$name

names(all_plots)
[1] "Survival curve by treatmeant for celltype: squamous" 
[2] "Survival curve by treatmeant for celltype: smallcell"
[3] "Survival curve by treatmeant for celltype: adeno"    
[4] "Survival curve by treatmeant for celltype: large"    

These will be used as our figure captions in the pdf.

In this final step, we can pass in the names of the list to the fig.cap option in the knitr chunk, and set results = 'asis' like so

```{r fig.cap=names(all_plots), results='asis'}
```

In that chunk we can use a loop that prints each element in our list (in this case our plots) and also a \newpage command after each plot.

for(plot in names(all_plots)){
  print(all_plots[[plot]])
  cat('\\newpage')
}

Below is an example of the output.

Now, this was only with three groups, so it probably wouldn’t have been too much trouble to write out manually. However with 50 or 100 groups, this workflow can come in very handy!

Acknowledgments

All thanks goes to Michael Harper for his great answer to this stack overflow post: https://stackoverflow.com/questions/52788015/looping-through-a-list-of-ggplots-and-giving-each-a-figure-caption-using-knitr

Reuse

Text and figures are licensed under Creative Commons Attribution CC BY 4.0. The figures that have been reused from other sources don't fall under this license and can be recognized by a note in their caption: "Figure from ...".

Citation

For attribution, please cite this work as

Fisher (2021, Jan. 29). Data, Code & Coffee: Many models, many plots, many pages!. Retrieved from https://hfshr.xyz/posts/2021-01-29-many-models-many-plots/

BibTeX citation

@misc{fisher2021many,
  author = {Fisher, Harry},
  title = {Data, Code & Coffee: Many models, many plots, many pages!},
  url = {https://hfshr.xyz/posts/2021-01-29-many-models-many-plots/},
  year = {2021}
}