36

I am trying to figure out how to create a loop that inserts some text into the rmarkdown file, and then produces the graph or table that corresponds to that header. The following is how I picture it working:

for(i in 1:max(month)){
### `r month.name[i]` Air quaility

```{r, echo=FALSE}
plot(airquality[airquality$Month == 5,])
```
}

This ofcourse just prints the for loop as text, if i surround the for loop with r`` I would just get an error.

I want the code to produce an rmd file that looks like this:

May Air Quality

Plot

June Air Quality

plot

and so on and so forth. any ideas? I cannot use latex because I at my work they do not let us download exe files, and I do not know how to use latex anyways. I want to produce a word document.

Isaac Fratti
  • 385
  • 1
  • 3
  • 8

2 Answers2

56

You can embed the markdown inside the loop using cat().

Note: you will need to set results="asis" for the text to be rendered as markdown. Note well: you will need two spaces in front of the \n new line character to get knitr to properly render the markdown in the presence of a plot out.

# Monthly Air Quality Graphs
```{r pressure,fig.width=6,echo=FALSE,message=FALSE,results="asis"}

attach(airquality)
for(i in unique(Month)) {
  cat("  \n###",  month.name[i], "Air Quaility  \n")
  #print(plot(airquality[airquality$Month == i,]))
  plot(airquality[airquality$Month == i,])
  cat("  \n")
}
```
jclouse
  • 2,129
  • 1
  • 18
  • 23
  • WoW thats super helpfull (please mark as correct answer) - it also answers this question: http://stackoverflow.com/questions/17178831/generate-markdown-comments-within-for-loop – Timo Kvamme Oct 20 '16 at 13:27
  • 13
    Where on earth is that "2 spaces in front of \n" documented? – Brandon Bertelsen Mar 30 '18 at 22:24
  • 1
    I try this solution in my R Notebook and get May Air Quality June Air Quality plot plot i.e., my text outputs are all jammed together in one block and then the graphs come along. Anyone know what's up with that? – David Kaufman May 29 '18 at 13:36
  • 2
    One drawback might be that we cannot do cross-reference now. – Liang Zhang Jun 15 '18 at 13:22
  • 1
    Great answer. It can probably be helpful to use multiline strings and the glue package if one is trying to get even closer to the „feel“ of actually looping around some longer markdown text: cat(glue("...")) – Magnus Sep 20 '20 at 23:11
  • I've also seen this documented similarly here. https://bookdown.org/yihui/rmarkdown-cookbook/results-asis.html – fullera Jul 06 '21 at 05:28
9

As mentioned here, you could also make use of the pander package:

# Monthly Air Quality Graphs
```{r pressure2, fig.width=6, echo=FALSE, message=FALSE, results="asis"}
library(pander)
for (i in unique(airquality$Month)) {
   # Inserts Month titles
   pander::pandoc.header(month.name[i], level = 3)
   # Section contents
   plot(airquality[airquality$Month == i,])
   # adding also empty lines, to be sure that this is valid Markdown
   pander::pandoc.p('')
   pander::pandoc.p('')
}
```
andschar
  • 2,731
  • 1
  • 23
  • 32
  • 1
    For me, this should be the answer due to simplicity. Managing `cat(' \n')` everywhere proved cumbersome and was causing some errors in an entire document if it was not positioned correctly in one section. – fullera Jul 12 '21 at 01:19
  • @andschar Could you have a look [here](https://stackoverflow.com/q/56983105/5784831)? It seems, you suggestion gets close, but I still face problems with the leaflet map. (And I am not sure, whether {.tabset} works with pander.) Thanks a lot. – Christoph Jul 20 '21 at 13:39