Search code examples
rggplot2knitrr-markdowntidyverse

Print RMarkdown captions from a loop


I am creating a series of plots from within a loop in an RMarkdown document, then knitting this to a PDF. I can do this without any problem, but I would like the caption to reflect the change between each plot. A MWE is shown below:

---
title: "Caption loop"
output: pdf_document
---

```{r, echo=FALSE}
library(tidyverse)

p <- 
  map(names(mtcars), ~ggplot(mtcars) +
      geom_point(aes_string(x = 'mpg', y = .))) %>% 
  set_names(names(mtcars))
```

```{r loops, fig.cap=paste(for(i in seq_along(p)) print(names(p)[[i]])), echo=FALSE}
for(i in seq_along(p)) p[[i]] %>% print
```

I have made a first attempt at capturing the plots and storing in a variable p, and trying to use that to generate the captions, but this isn't working. I haven't found too much about this on SO, despite this surely being something many people would need to do. I did find this question, but it looks so complicated that I was wondering if there is a clear and simple solution that I am missing.

I wondered if it has something to do with eval.after, as with this question, but that does not involve plots generated within a loop.

many thanks for your help!


Solution

  • It seems that knitr is smart enough to do the task automatically. By adding names(mtcars) to the figure caption, knitr iterates through these in turn to produce the correct caption. The only problem now is how to stop all of the list indexes from printing in the document...

    ---
    title: "Caption loop"
    output: pdf_document
    ---
    
    ```{r loops, fig.cap=paste("Graph of mpg vs.", names(mtcars)), message=FALSE, echo=FALSE, warning=FALSE}
    library(tidyverse)
    
    map(
      names(mtcars),
      ~ ggplot(mtcars) +
        geom_point(aes_string(x = 'mpg', y = .))
    )
    ```