17
votes

The results = 'asis' chunk option within Rmarkdown allows one to easily dynamically create text including headers. However, I wish to dynamically create a header with the asis option, but then in the same code chunk insert some graphics.

The most related answer I could find for this is here: Programmatically insert text, headers and lists with R markdown, but the answer to this question does not allow both dynamic headers and plots within those dynamic headers.

Here is a simple reproducible example follows demonstrating what I can and cannot achieve with results = 'asis'

The code directly below does what I would expect, creating a header for each Species.

---
output: html_document
---
```{r echo = FALSE, results ='asis'}
for(Species in levels(iris$Species)){
  cat('#', Species, '\n')
}
```

The code directly below here does not do what I would like. Ideally, the code directly below would generate a header for each Species with a plot underneath each header. Instead, it generates the single setosa header in the output file followed by the three plots.

---
output: html_document
---
```{r echo = FALSE, results ='asis'}
library(ggplot2)
for(Species in levels(iris$Species)){
  cat('#', Species, '\n')
  p <- ggplot(iris[iris$Species == Species,], aes(x = Sepal.Length, y = Sepal.Width)) +
    geom_point()
  print(p)
}
```

Is there some way to dynamically generate the 3 headers with a plot under each header?

1

1 Answers

25
votes

You need to add some new lines after the plots and before the headers, using cat('\n'):

```{r echo = FALSE, results ='asis'}
library(ggplot2)
for(Species in levels(iris$Species)){
  cat('\n#', Species, '\n')
  p <- ggplot(iris[iris$Species == Species,], aes(x = Sepal.Length, y = Sepal.Width)) +
    geom_point()
  print(p)
  cat('\n')
}