4

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!

Community
  • 1
  • 1
Jonny
  • 2,703
  • 2
  • 27
  • 35
  • I might not have understood the question correctly, but the issue might just be that there is no title to the plots. If we just want the currently plotted variables in the titile, we can add `+ ggtitle(.)` to the `~ggplot` statement – R.S. Mar 04 '17 at 07:26
  • adding a caption to the figure makes it text-searchable. – flies Nov 09 '18 at 19:14

2 Answers2

4

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 = .))
)
```
Jonny
  • 2,703
  • 2
  • 27
  • 35
  • 2
    "The only problem now is how to stop all of the list indexes from printing in the document" yes!! please help! – flies Jan 15 '19 at 21:05
1

In case this might be useful to somebody. Here is an adaptation of Jonny's solution for captions without printing list indices. This can be achieved by using purrr::walk instead of purrr::map. Also included is a latex fig label and text that references each plot.

---
title: "Loop figures with captions"
output: 
    pdf_document
---


```{r loops, fig.cap=paste(sprintf("\\label{%s}", names(mtcars)), "Graph of mpg vs.", names(mtcars)),results='asis', message=FALSE, echo=FALSE, warning=FALSE}
library(tidyverse)
library(stringi)
walk(names(mtcars),
     ~{
         p <- ggplot(mtcars) +
             geom_point(aes_string(x = 'mpg', y = .))
         #print plot
         cat('\n\n') 
         print(p)
         #print text with refernce to plot
         cat('\n\n') 
         cat(sprintf("Figure \\ref{%s} is a Graph of mpg vs. %s. %s \n\n", ., ., 
                     stri_rand_lipsum(1)))
         cat("\\clearpage")
     })
```
LiamS
  • 41
  • 4