Parameterized Reporting in R

Use RMarkdown and Knitr to generate multiple interactive reports based on a set of parameters.

January 16, 2021

Just give me the code

Skip all this and jump to the parameterized-reporting-example.Rmd file in my parameterized-reporting repo.

About parametrized reports

This is a parameterized report written in in R Markdown. It consists of a combination of text and code chunks and uses R, pandoc, and LaTeX to connect to a data source, create visualizations, and export a single file to html, pdf, or word without changing the code. The resulting pages stand on their own, have no dependencies, and can be shared or stored on a central location, like git pages, a site on netlify, or a sharepoint documents library. The data and code are readily accessible for transparency and reproducibility.

Each export format has its own advantages:

html word pdf
Standalone X X X
Easy print X X
Editable X
Static charts/maps X X X
Interactive charts/maps X
Embed data for download X

For good documentation, check out:

Example Report elements for pontiac

Start by pulling down a csv from GitHub to use in this example:

csv_url <- "https://raw.githubusercontent.com/tidyverse/ggplot2/master/data-raw/mpg.csv"

download.file(csv_url, destfile = "mpg.csv", method = "curl")
df <- data.table::fread("mpg.csv")

Parameter Specfic Charts

Next, I’m going to insert the params that I defined in the yml header of this document into the R code to come up with some inline statistics.

For example, the yml header of this post looks like this - look at the params:

title: Parameterized Reporting in R
author: rjfranssen
date: '2021-01-16'
slug: parameteried-reporting-in-r
categories:
  - helps
tags:
  - r
params:
  manufacturer: pontiac
  date: !r lubridate::today()

The manufacturer pontiac has 5 vehicles in this dataset.
They average 17 mpg city and 26.4 mpg highway.

Vehicle Counts

df2 <- df[df$manufacturer == params$manufacturer, ]
  
plt <- ggplot(df2) +
  geom_bar( aes(x = as.factor(cyl), fill = as.factor(cyl)), stat = 'count') +
  scale_fill_viridis_d(option = "viridis") +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
  theme(legend.position = "none")

plt

MPGs

df2 <- df[df$manufacturer == params$manufacturer, ]
  
plt <- ggplot(df2) +
  geom_point(aes(x = displ, y = hwy, color = as.factor(year), label = model), size = 5) +
  scale_color_viridis_d(option = "viridis") +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
  theme(legend.position = "none")

plt

All Car Manufacturers

Vehicle Counts

plt <- ggplot(df) +
  geom_bar( aes(manufacturer, fill = manufacturer), stat = 'count') +
  scale_fill_viridis_d(option = "viridis") +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
  theme(legend.position = "none")

plt

MPGs

plt <- ggplot(df) +
  geom_point(aes(x = cty, y = hwy, color = manufacturer), alpha = 0.6) +
  scale_fill_viridis_d(option = "viridis") +
  facet_wrap(~manufacturer) +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
  theme(legend.position = "none") 

plt

Lastly, I’m going to use the below function to read in the .Rmd file and ouput an html file using the parameters as inputs. Then, I’m going to run this function for each manufacturer in the sample dataset to generate a custom report for each manufactuer.

Credit: bookdown docs and this stackoverflow post

# Function to render this rmd file as an html doc; run this in R console
render_report = function(manufacturer = params$manufacturer, date = params$date) {
  rmarkdown::render(
    input = "parameterized-reporting-example.Rmd",
    output_format = "html_document",
    params = list(
      manufacturer = manufacturer,
      date = date
    ),
    output_file = paste0(manufacturer, "_mpg_report_", date, ".html")
  )
}

# Test one-off report with default params
render_report()

# Now loop through and create one report for each manufacturer
# (note: need to pull down the file and create `df` before running)
for (i in unique(df$manufacturer)){
  render_report(manufacturer = i)
  print(paste0('finished knitting ', i))
}

Final report!

The final report will look like this (see full screen)

Acknowledgements

This blog post was made possible thanks to: