Programmatically create new headings and outputs in Rmarkdown

Negative Space (Pexels)

I often find myself performing analyses looped over certain parts of the data in my Rmarkdown. I like seeing the output under different headings in the final output for easy navigation. Although it is rather simple, I can never remember the recipe for this right away, and as a result, I keep digging into old rmd files and the all-knowing internet. I decided to write this down once and for all to break the cycle and save my future self some time and prevent moments like this:

computer

Points to remember:

  • Set chunk option results="asis"
  • Create headings using cat() function in loop
  • Call print() on the code to generate desired output (tables, plots, code output, etc)
  • Wrap the output with appropriate HTML tags
    • For DT::datatable outputs initiate dependencies previously and use htmltools::tagList()
    • For neatly rendered console outputs, wrap the code with htmltools::pre() and htmltools::code().

1. Example for creating tables in loop:

I have run into an issue before where tables printed in loop don’t render in the final document. As suggested in this SO post, creating an initial datatable is needed to load some magic dependencies. To hide this chunk (and the unnecessary datatable) from the final output though, you can set chunk option include=FALSE:

```{r, include=FALSE}

library(DT)

datatable(iris)

```

The chunk below will create new headings with the names within the list (e.g. data1, data2, and data3) and show a datatable. Check out the documentation to further customize the table (filters, conditional formatting, captions are a few things that make the tables more useful).

```{r, results="asis"}

library(htmltools)

list_to_output <- list(data1 = iris,
                       data2 = mtcars,
                       data3 = airquality)

for(i in names(list_to_output)){
  
  cat("\n") 
  cat("##", i, "\n") # Create second level headings with the names.
  
  print(
   tagList(
    datatable(list_to_output[[i]])
   )
  )
  
  cat("\n")
  
}

```

2. Example for creating console output:

We need to wrap the code output in <pre> and <code> tags for rendering properly. You can do this manually or use htmltools R package for this. Without these tags, the console output will render like normal text. This is especially helpful if you are trying to print named vectors where the name and the value will be aligned neatly.

```{r, results="asis"}

for(i in paste("Output", 1:3)){
  
  cat('\n') 
  cat("###", i, "\n")
  
  
  vec <- 1:10
  
  pre(       # can use tags manually as well: <pre><code>BlaBlaBla</code></pre>
   code(
      print(vec)   
   )
  )
  
  
}
```

3. Example for creating plot output:

This one is more straightforward since we don’t need to deal with HTML tags specifically:

```{r, fig.width=3, fig.height=3, results="asis"}

for(i in paste("Plot", 1:3)){
  
  cat('\n') 
  cat("###", i, "\n")

print(
  ggplot(iris) +
    geom_point(aes(x=Sepal.Length, y=Petal.Length))
)

cat('\n')

}

```
Atakan Ekiz
Atakan Ekiz
Scientist, storyteller, data lover
comments powered by Disqus