R Markdown Reporting Best Practices

By:
Eduardo Almeida
September 8, 2022

Working with R Markdown allows you to create different types of reports, from static websites to PDFs and slides in R. Many of them come with templates, but also let you adjust for specific user needs.  This makes R Markdown easy to use and an efficient way to turn data analyses into cohesive, high-quality reports.  With R Markdown you can create reproducible and shareable documentation. Users can create reports for evaluation by different pairs or through the community, following best practices such as <a href="https://appsilon.com/gxp-compliance-in-pharma-made-easier-good-documentation-practices-with-r-markdown-and-officedown/" target="_blank" rel="noopener">GxP Compliance with R Markdown</a>. <blockquote>Are you looking for a multilingual version of R Markdown? Try <a href="https://appsilon.com/r-quarto-tutorial/" target="_blank" rel="noopener">Quarto, for interactive Markdown documents</a>.</blockquote> In this post, we’ll present the different types of formats that R Markdown can design and how to create them. We’ll also cover several tips and materials when working with each. Continue reading to master R Markdown.  <ul><li><a href="#yaml">YAML and R Markdown</a></li><li><a href="#render">Rendering Documents</a></li><li><a href="#read">1. Reading the documentation</a></li><li><a href="#rstudio">2. Leverage Rstudio UI and package templates</a></li><li><a href="#template">3. Create your own templates</a></li><li><a href="#separate">4. Separate the document into pieces</a></li><li><a href="#params">5. Using params</a></li><li><a href="#extension">6. Extensions</a></li></ul> <hr /> <h2>R Markdown Reporting - Documents</h2> The steps required to create R Markdown reports are set primarily by <a href="https://yihui.org/knitr/" target="_blank" rel="nofollow noopener">knitr</a> and <a href="https://pandoc.org/" target="_blank" rel="nofollow noopener">pandoc</a>, but also other extensions such as <a href="https://www.latex-project.org/" target="_blank" rel="nofollow noopener">latex</a> with <a href="https://yihui.org/tinytex/" target="_blank" rel="nofollow noopener">tinytex</a>. <img class="size-full wp-image-15563 aligncenter" src="https://webflow-prod-assets.s3.amazonaws.com/6525256482c9e9a06c7a9d3c%2F65b01d34832c47d6731174c8_r-markdown-reporting-workflow.webp" alt="R Markdown reporting workflow steps" width="1554" height="739" /> How many file formats can R Markdown render? R Markdown can render formats from HTML docs, Notebooks, PDFs, Word docs, OpenDocument text, Rich text, Markdown variants, vignettes - and that's just covering documents some more include: <ul><li style="font-weight: 400;" aria-level="1"><a href="https://bookdown.org/yihui/rmarkdown/html-document.html" target="_blank" rel="nofollow noopener">html_document </a>- HTML document w/ Bootstrap CSS</li><li style="font-weight: 400;" aria-level="1"><a href="https://bookdown.org/yihui/rmarkdown/pdf-document.html" target="_blank" rel="nofollow noopener">pdf_document </a>- PDF document (via LaTeX template)</li><li style="font-weight: 400;" aria-level="1"><a href="https://bookdown.org/yihui/rmarkdown/word-document.html" target="_blank" rel="nofollow noopener">word_document </a>- Microsoft Word document (docx)</li><li style="font-weight: 400;" aria-level="1"><a href="https://bookdown.org/yihui/rmarkdown/markdown-document.html" target="_blank" rel="nofollow noopener">md_document </a>- Markdown document (various flavors)</li><li style="font-weight: 400;" aria-level="1"><a href="https://bookdown.org/yihui/rmarkdown/ioslides-presentation.html" target="_blank" rel="nofollow noopener">ioslides_presentation </a>- HTML presentation with ioslides</li><li style="font-weight: 400;" aria-level="1"><a href="https://bookdown.org/yihui/rmarkdown/revealjs.html" target="_blank" rel="nofollow noopener">revealjs::revealjs_presentation </a>- HTML presentation with reveal.js</li><li style="font-weight: 400;" aria-level="1"><a href="https://bookdown.org/yihui/rmarkdown/slidy-presentation.html" target="_blank" rel="nofollow noopener">slidy_presentation </a>- HTML presentation with W3C Slidy</li><li style="font-weight: 400;" aria-level="1"><a href="https://bookdown.org/yihui/rmarkdown/powerpoint-presentation.html" target="_blank" rel="nofollow noopener">powerpoint_presentation</a>: PowerPoint presentation</li><li style="font-weight: 400;" aria-level="1"><a href="https://rmarkdown.rstudio.com/flexdashboard/" target="_blank" rel="nofollow noopener">flexdashboard::flex_dashboard</a> - Interactive dashboards</li><li style="font-weight: 400;" aria-level="1"><a href="https://bookdown.org/yihui/rmarkdown/tufte-handouts.html" target="_blank" rel="nofollow noopener">tufte::tufte_html</a> - HTML handouts in the style of Edward Tufte</li><li style="font-weight: 400;" aria-level="1"><a href="https://bookdown.org/yihui/rmarkdown/r-package-vignette.html" target="_blank" rel="nofollow noopener">html_vignette </a>- R package vignette (HTML)</li><li style="font-weight: 400;" aria-level="1"><a href="https://rmarkdown.rstudio.com/github_document_format.html" target="_blank" rel="nofollow noopener">github_document </a>- GitHub Flavored Markdown document</li></ul> It is worth mentioning that R Markdown <a href="https://yihui.org/knitr/" target="_blank" rel="nofollow noopener">knitr</a> can execute code in other languages besides R, including: <ul><li style="font-weight: 400;" aria-level="1">Python</li><li style="font-weight: 400;" aria-level="1">SQL</li><li style="font-weight: 400;" aria-level="1">Julia</li><li style="font-weight: 400;" aria-level="1">JavaScript</li><li style="font-weight: 400;" aria-level="1">CSS</li></ul> If you're searching for a specific language, search the <a href="https://github.com/yihui/knitr-examples" target="_blank" rel="nofollow noopener">knitr repository</a> for the [language] + "engine." <blockquote>Looking to step up your presentations with R? See how easy it is to <a href="https://appsilon.com/r-markdown-powerpoint-presentation/" target="_blank" rel="noopener">create PowerPoint Presentations with R Markdown</a>.</blockquote> <h2 id="yaml">YAML and R Markdown</h2> In order to define which type of document the report will result in, knitr requires metadata that states the output format. This is done in the YAML header of the R Markdown file: <img class="size-full wp-image-15569 aligncenter" src="https://webflow-prod-assets.s3.amazonaws.com/6525256482c9e9a06c7a9d3c%2F65b01d3560c4b5e759a8a078_yaml-header-code-chunk-1.webp" alt="YAML header in R Markdown file for report doc type" width="1369" height="771" /> YAML contains a set of arguments that each document can have. Even different packages can have their own set of rules that can be adjusted through the YAML component It usually is set on the header of the R Markdown document but can also be used as a separate file. YAML is an extensible approach to metadata. That means that any metadata that is incorrect will fail silently. This may cause issues in passing the correct information or what is available by the package. Because of this, <a href="https://ymlthis.r-lib.org/" target="_blank" rel="nofollow noopener">ymlthis</a> is a package that gathers the most common approaches when setting YAML for R markdown documents. It contains a <a href="https://ymlthis.r-lib.org/articles/yaml-fieldguide.html" target="_blank" rel="nofollow noopener">yaml fieldguide</a> that shares the most common sources of YAML. The ymlthis addon saves a lot of time when setting up the YAML configuration. This is possible  because it has a set of the most common configuration for many types of well-known documents: <img class="size-full wp-image-15559 aligncenter" src="https://webflow-prod-assets.s3.amazonaws.com/6525256482c9e9a06c7a9d3c%2F65b01d37e9c00d5eac1275af_new-yaml-1.gif" alt="common confis for markdown reporting types" width="480" height="580" /> <h2 id="render">Rendering Documents</h2> It should be clear by now that changing the type of document is basically changing the YAML option to be run. In most cases, this will be more than enough and Rstudio provides a brief summary of the required approach on their cheatsheet and <a href="https://www.rstudio.com/wp-content/uploads/2015/03/rmarkdown-reference.pdf" target="_blank" rel="nofollow noopener">R Markdown reference</a>: <img class="size-full wp-image-15571 aligncenter" src="https://webflow-prod-assets.s3.amazonaws.com/6525256482c9e9a06c7a9d3c%2F65b01d38cb85d9eead740f85_yaml-output-1.webp" alt="YAML output options cheatsheet" width="1345" height="593" /> <h2>R Markdown Reporting Best Practices</h2> Because R Markdown has a lot of flexibility, some guidelines and best practices can help improve productivity and reduce common errors. If you want to be an R Markdown expert, start with these best practices: <h3 id="documentation">1. Read the documentation first</h3> This may seem straightforward, but the truth is: There is no better place to understand the appropriate metadata and design of the markdown document than with the maintainer. For packages that are so well adopted like R Markdown, most common issues and expected behavior are already documented. Save time and headaches by going to the source.  <h3 id="rstudio">2. Leverage Rstudio UI and package templates</h3> When rendering new R Markdown documents, you can use templates from Rstudio UI and leverage the options that new packages can have. You can see an example view here: <img class="size-full wp-image-15567 aligncenter" src="https://webflow-prod-assets.s3.amazonaws.com/6525256482c9e9a06c7a9d3c%2F65b01d3a99f2296f27b4ca38_template-for-r-markdown-reporting.webp" alt="R Markdown document template from RStudio UI" width="544" height="285" /> <h3 id="template">3. Create your own templates for R Markdown</h3> Making your own templates will boost your productivity and keep you with steady-state documents. This can be used through many types of documents such as <a href="https://bookdown.org/yihui/rmarkdown-cookbook/word-template.html" target="_blank" rel="nofollow noopener">word documents</a> or even HMTL documents, including slides, by setting your own <a href="https://bookdown.org/yihui/rmarkdown-cookbook/html-template.html" target="_blank" rel="nofollow noopener">HTML</a> and/or <a href="https://bookdown.org/yihui/rmarkdown-cookbook/html-css.html" target="_blank" rel="nofollow noopener">CSS</a> template. <a href="https://rstudio.github.io/bslib/" target="_blank" rel="nofollow noopener">Bslibs</a> is a great resource when setting the UI design since it allows you to dynamically set the CSS components: <img class="size-full wp-image-15557 aligncenter" src="https://webflow-prod-assets.s3.amazonaws.com/6525256482c9e9a06c7a9d3c%2F65b01d3b99f56874983562c5_bslib-and-r-markdown-reporting.webp" alt="Dynamically set css components in Markdown templates with bslib" width="1084" height="659" /> <h3 id="separate">4. Separate the document into different pieces</h3> This is not only important to make your code cleaner but also reusable. Let’s take the {xaringan} package as an example: <pre><code> --- title: "R Markdown examples" author: "Author" date: "`r Sys.Date()`" output:  xaringan::moon_reader:    css: xaringan-themer.css params:  data: !r mtcars  variable: "Species" always_allow_html: true --- <br>```{r setup, include=FALSE} knitr::opts_chunk$set(echo = TRUE) library(tidyverse) library(GGally) library(xaringanExtra) library(DT) library(skimr) library(knitr) library(png) library(leaflet) ``` <br> ```{r, child="preamble.Rmd"} <br>``` </code></pre> <pre><code> ```{r xaringanExtra-clipboard, echo=FALSE} xaringanExtra::use_clipboard() xaringanExtra::use_tile_view() xaringanExtra::use_editable(expires = 1) xaringanExtra::use_scribble() xaringanExtra::use_search(show_icon = TRUE) xaringanExtra::use_fit_screen() xaringanExtra::use_clipboard() xaringanExtra::use_tachyons() <br>``` <br>```{r xaringan-themer, include=FALSE, warning=FALSE} library(xaringanthemer) style_mono_accent(  base_color = "#1a317e",  header_font_google = google_font("Josefin Sans"),  text_font_google   = google_font("Montserrat", "300", "300i"),  code_font_google   = google_font("Fira Mono") ) ``` </code></pre> <img class="size-full wp-image-15575 aligncenter" src="https://webflow-prod-assets.s3.amazonaws.com/6525256482c9e9a06c7a9d3c%2F65b01d3d82ec012c9c5a086d_r-markdown-examples-code-output.webp" alt="r markdown reporting example output" width="397" height="207" /> Separating the required components of the {xaringan} into a different document makes it reusable and easier to change any behavior regarding the slide components. It also creates a better understanding of the workflow such as in the example of <a href="https://www.rstudio.com/blog/automated-survey-reporting/" target="_blank" rel="nofollow noopener">using {pins} with R Markdown</a>. Additionally, you can set conditional behaviors that change the workflow of the report like the <a href="https://solutions.rstudio.com/r/blastula/conditional-example/" target="_blank" rel="nofollow noopener">Conditional Emails with RStudio Connect</a>. <h3 id="params">5. Using params in R Markdown</h3> Params allow you to dynamically change the parameters of the R Markdown document when you knit: <img class="alignnone size-full wp-image-15561" src="https://webflow-prod-assets.s3.amazonaws.com/6525256482c9e9a06c7a9d3c%2F65b01d3eb4843141c14f2781_params-1.webp" alt="dynamically changing parameters of R Markdown documents with params" width="1032" height="379" /> This adds a new layer to R Markdown flexibility. Using params allows you to have a reactive component as input for Shiny development: <pre><code> library(shiny) library(rmarkdown) <br>ui = fluidPage(  textInput("user", "Name"),  downloadButton("markdown", "Get report") ) <br>server &lt;- function(input, output, session) {    output$markdown &lt;- downloadHandler(    filename = "RMD_report.html",        content = function(file) {      params &lt;- list(name = input$user)            rmarkdown::render(        "./report.rmd",        output_file = file,        params = params,        envir = new.env(parent = globalenv())      )    }  ) } <br>shinyApp(ui, server) </code></pre> <pre><code> --- title: "Hello, world!" output: html_document params:  name: "User" ---   ```{r} params$name ``` </code></pre> <img class="alignnone size-full wp-image-15578" src="https://webflow-prod-assets.s3.amazonaws.com/6525256482c9e9a06c7a9d3c%2F65b01d40f072657ad683fb0e_hello-world-params.webp" alt="R Markdown html doc reporting" width="1012" height="277" /> <h3 id="extension">6. Extensions in R Markdown</h3> There are a variety of extension options when we’re working with R Markdown. We’ve collected a few and below is a small summary of information from use cases and materials: <table style="height: 1117px;" width="695"> <tbody> <tr> <td><b>Type</b></td> <td><b>Summary</b></td> <td><b>Link</b></td> </tr> <tr> <td>YAML Header</td> <td>Markdown variants documents</td> <td><a href="https://bookdown.org/yihui/rmarkdown/markdown-document.html" target="_blank" rel="nofollow noopener">R Markdown: The Def. Guide</a></td> </tr> <tr> <td>Code Chunks</td> <td>Convert models to equations</td> <td><a href="https://bookdown.org/yihui/rmarkdown-cookbook/equatiomatic.html" target="_blank" rel="nofollow noopener">R Markdown Cookbook</a></td> </tr> <tr> <td>Code Chunks</td> <td>Control the width of text output</td> <td><a href="https://bookdown.org/yihui/rmarkdown-cookbook/text-width.html" target="_blank" rel="nofollow noopener">R Markdown Cookbook</a></td> </tr> <tr> <td>Code Chunks</td> <td>Control the size of plots/images</td> <td><a href="https://bookdown.org/yihui/rmarkdown-cookbook/figure-size.html" target="_blank" rel="nofollow noopener">R Markdown Cookbook</a></td> </tr> <tr> <td>Code Chunks</td> <td>Figure alignment</td> <td><a href="https://bookdown.org/yihui/rmarkdown-cookbook/fig-align.html" target="_blank" rel="nofollow noopener">R Markdown Cookbook</a></td> </tr> <tr> <td>Code Chunks</td> <td>Verbatim code</td> <td><a href="https://bookdown.org/yihui/rmarkdown-cookbook/verbatim-code-chunks.html" target="_blank" rel="nofollow noopener">R Markdown Cookbook</a></td> </tr> <tr> <td>Code chunks</td> <td>Embed a web page</td> <td><a href="https://bookdown.org/yihui/rmarkdown-cookbook/include-url.html" target="_blank" rel="nofollow noopener">R Markdown Cookbook</a></td> </tr> <tr> <td>Code Chunks</td> <td>Conditional chunks</td> <td><a href="https://bookdown.org/yihui/rmarkdown-cookbook/chunk-variable.html" target="_blank" rel="nofollow noopener">R Markdown Cookbook</a></td> </tr> <tr> <td>Formatted text</td> <td>Multi-column layout</td> <td><a href="https://bookdown.org/yihui/rmarkdown-cookbook/multi-column.html" target="_blank" rel="nofollow noopener">R Markdown Cookbook</a></td> </tr> <tr> <td>Formatted text</td> <td>Code results with appropriate layout PDF</td> <td><a href="https://intro2r.com/tips_tricks.html#tips_tricks" target="_blank" rel="nofollow noopener">Introduction to R</a></td> </tr> <tr> <td>Formatted text</td> <td>Suppress loading packages on Rmd</td> <td><a href="https://intro2r.com/tips_tricks.html#tips_tricks" target="_blank" rel="nofollow noopener">Introduction to R</a></td> </tr> <tr> <td>Formatted text</td> <td>Choose a variety of fonts from google</td> <td><a href="https://fonts.google.com/" target="_blank" rel="nofollow noopener">Google Fonts</a></td> </tr> <tr> <td>Packages</td> <td>Template ready HTML documents</td> <td><a href="https://juba.github.io/rmdformats/index.htmlhttps:/juba.github.io/rmdformats/index.html" target="_blank" rel="nofollow noopener">Rmdformats</a></td> </tr> <tr> <td>Packages</td> <td>Template ready HTML documents</td> <td><a href="https://prettydoc.statr.me/themes.html" target="_blank" rel="nofollow noopener">Prettydoc</a></td> </tr> <tr> <td>Packages</td> <td>Colaborate Rmd on Google Drive</td> <td><a href="https://claudiozandonella.github.io/trackdown/" target="_blank" rel="nofollow noopener">trackdown</a></td> </tr> <tr> <td>Packages</td> <td>Research project as a website</td> <td><a href="https://workflowr.github.io/workflowr/" target="_blank" rel="nofollow noopener">workflowr</a></td> </tr> <tr> <td>Packages</td> <td>Send emails based on R Markdown</td> <td><a href="https://github.com/rstudio/blastula" target="_blank" rel="nofollow noopener">blastula</a></td> </tr> </tbody> </table> <h2>Concluding R Markdown Reporting Tips</h2> In this blog post, we discussed some of the best practices when working with R Markdown documents. You’ve learned a few best practices including:: <ul><li style="font-weight: 400;" aria-level="1">Always reading the documentation first (trust me, it's worth it)</li><li style="font-weight: 400;" aria-level="1">Leverage Rstudio UI and package templates</li><li style="font-weight: 400;" aria-level="1">Create your own templates</li><li style="font-weight: 400;" aria-level="1">Separate the document into different pieces</li><li style="font-weight: 400;" aria-level="1">Use params</li></ul> <blockquote>Looking for more tips? Check out these <a href="https://appsilon.com/r-markdown-tips/" target="_blank" rel="noopener">tips for code, images, comments, and tables in R Markdown</a>.</blockquote> There are plenty of amazing things you can achieve with R and R Markdown. But it’s important to keep reusability and adoption in mind. Be sure to stay consistent and write <a href="https://appsilon.com/best-practices-for-durable-r-code/" target="_blank" rel="noopener">durable r code</a> and <a href="https://appsilon.com/how-to-write-production-ready-r-code/" target="_blank" rel="noopener">production-ready code</a> that will last.  These will help you not only become an R Markdown wiz but a better overall R developer! What are your favorite practices to follow when working with R Markdown? Let us know in the comments or tag us on Twitter.

Have questions or insights?

Engage with experts, share ideas and take your data journey to the next level!

Is Your Software GxP Compliant?

Download a checklist designed for clinical managers in data departments to make sure that software meets requirements for FDA and EMA submissions.
Explore Possibilities

Share Your Data Goals with Us

From advanced analytics to platform development and pharma consulting, we craft solutions tailored to your needs.

Talk to our Experts
best practices
reporting
quarto
gxp