Automate parameterized reports or presentation with {xaringan}

Automate parameterized reports or presentation with {rmarkdown} and {xaringan}

2024-03-02

Introduction

The following short tutorial is to demonstrate the use of the {xaringan} package, {xaringanthemer} to make presentations with {rmarkdown} and {renderthis} to automate the exportation of each report/presentation. It is necessary to know about the use of the {purrr} package and its map() function to be able to automate the generation of reports.

Scenario:

Suppose you have to provide several provincial departments with a biweekly surveillance report. The information reported is the same, it is only updated according to the data collected in the period.

To facilitate the process you decide to share this summary report, as a presentation, where each part of it (table or graph) is a slide. Using an output created with rmarkdown in html or pdf format is very appropriate for the situation. The {xaringan} package is like a plugin for {rmarkdown} allowing you to create presentations with better style and control. Here is an explenation of the package.

How?

The template

  • The first step is to create a presentation template with rmarkdown using the available ones provided when you install {xaringan} and {xaringanthermer} (to make even easier the formatting of the template).
# install from CRAN

install.packages('xaringan') 
install.packages('xaringanthemer') 
# or  
pacman::p_load(xaringan, xaringanthemer)
  • The second step, after installing both packages, create a new presntation from Rstudio, new file, R Markdown, from templates, you can choose the version of “Ninja Themed Presentation” (from {xaringanthemer} or “Ninja Presentation” (by {xargingan}). The new document includes ~27 slides with examples of formats and elements that can be modified.There are several tutorials on the web on how to work with xaringan like this one or this in spanish.
  • The third step is to modify the YAML section so that the creation of each presentation based on parameters can be automated (for example, provincial department) as follows:
---
title: "Status of several events"  
subtitle: "biweekly summary"  
author: ""
date: '`r Sys.Date()`'
output:
  xaringan::moon_reader:
    self_contained: true  #add this command for html self-contained files.
    css: xaringan-themer.css
    nature:
      slideNumberFormat: "%current%"
      highlightStyle: github
      highlightLines: true
      ratio: 16:9
      countIncrementalSlides: true

params:                 # This command must be declared to be able to specify parameters
  province: A    # Here the parameters are placed with their default values (without quotes!)
---
  • If you used the {xaringanthemer} template you will see that there is a code chunk with a function with pre-populated parameters (style_duo_accent) that allows you to make modifications to the entire presentation format. Here you can see more about the use of these functions and what you can do.

Here is a full example for the template: (when copy this code, replace the … (dots) per ` (back tick)) for the R code chunks

---
title: "Status of Event X"
subtitle: "biweekly summary"  
author: ""
date: '`r Sys.Date()`'
output:
  xaringan::moon_reader:
    self_contained: true
    css: xaringan-themer.css
    nature:
      slideNumberFormat: "%current%"
      highlightStyle: github
      highlightLines: true
      ratio: 16:9
      countIncrementalSlides: true

params: 
  province: A
---

...{r setup, include=FALSE} #remember replace the dots (...) with backticks (```)
options(htmltools.dir.version = FALSE)
knitr::opts_chunk$set(
  fig.width=9, fig.height=3.5, fig.retina=3,
  out.width = "100%",
  cache = FALSE,
  echo = TRUE,
  message = FALSE, 
  warning = FALSE,
  hiline = TRUE
)
# this section is to load your data or other process
#is advice to install pacman to install/load packages

pacman::p_load(tidyverse,  #for data management
               fabricatr,  #to generate fake data
               janitor,    #for summary tables
               flextable,  #for tables formating
               epikit)     #for age categories
seed=101
data_surveillance <- fabricate(
 
   N=1000,
  
  id_prov=rep(1:200, 5),
  
  age=abs(draw_normal_icc(mean=50, 
                          N=N, 
                          clusters = id_prov,
                          sd_between = 10, 
                          ICC=0.5)
          ),
  sex=draw_categorical(N=N,prob =c(0.5,0.5), 
                       category_labels = c("F", "M")
                       ),
  
  province=draw_categorical(N=N, 
                            prob=c(0.5,0.5,0.5,0.5,0.5),
                            category_labels = c("A","B","C","D","E")),
  outcome=draw_categorical(N=N, 
                           prob = c(0.03,0.97), 
                           category_labels = c("Death", "Alive"))
) %>% 
mutate(date = sample(seq(as.Date('2022-01-01'), as.Date('2023-12-01'), by="day"),1000, replace=T),
       age_groups=age_categories(age, lower = 0, upper=80, by=10))


# A table

table1 <- data_surveillance %>% 
  filter(province==params$province) %>%  #critical for automate, (this is the parameter variable)
  tabyl(age_groups, sex) %>% 
  adorn_totals("col") %>% 
  adorn_percentages("col") %>% 
  adorn_pct_formatting() %>% 
  adorn_ns() %>%
  flextable() %>% 
  set_header_labels(age_groups="Age Groups") %>%
  width(width = 1.5) %>% 
  theme_zebra()

#A graph

graph1 <- data_surveillance %>% 
  filter(province==params$province) %>% 
  ggplot(aes(x=date, fill=outcome))+
  geom_histogram(color="black", binwidth = 30)+
  labs(x="Date of care received",
       y="Number of cases")
... #remember replace the dots (...) with backticks (```)

...{r xaringan-themer, include=FALSE, warning=FALSE} #remember replace the dots (...) with backticks (```)
library(xaringanthemer)
style_duo_accent(
  primary_color = "#1381B0",
  secondary_color = "#FF961C",
  inverse_header_color = "#FFFFFF"
)
...

## Case distribution by Age groups and sex in **`r params$province`**

...{r table, echo=FALSE} #remember replace the dots (...) with backticks (```)
table1  
...   #remember replace the dots (...) with backticks (```)

---
## Epidemic curve by date of case admission in **`r params$province`**

...{r graph, echo=FALSE}
graph1+
  theme_xaringan() #a feature from xaringanthemer to match the theme with the presentation
...

The automation process

  • Now that we have the presentation template ready (saved in your disk, as .Rmd file), we now move on to the automation step. For this we are going to create a new script and install (only one time) the {reporthis} package.
    At the time writing this tutorial, the package was not in CRAN so the process to install is this:
# install.packages("remotes")

remotes::install_github("jhelvy/renderthis")

library(renderthis)
library(tidyverse) #you need to load tidyverse to load purrr
  • Next, create a vector with the items of each parameter or value to generate each report which is going to be use with map() from {purrr}
  • Here is the code :
library(tidyverse)
library(renderthis)
library(here) #this package is for the file routes

provinces=c("A", "B", "C", "D", "E") # Vector with the values to filter each report


map(.x= provinces,

    .f=possibly(~to_html(from=here("Untitled/Untitled.Rmd"),

             to= here(paste0("Untitled/reports/",.x,".html")),

             render_args=list(params=list(province=.x))
             )
        )
    )
  • The use of the function possibly() from purrr avoids to stop the generation of each report.
  • Try to create a separate folder for the outputs.
  • Also if you want to print the generated html into pdf (using to_pdf from {renderthis}, you need to install two additional packages, {pagedown} and {chromote}
> sessionInfo()
R version 4.3.1 (2023-06-16 ucrt)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 11 x64 (build 22621)

Matrix products: default


locale:
[1] LC_COLLATE=English_United States.utf8  LC_CTYPE=English_United States.utf8   
[3] LC_MONETARY=English_United States.utf8 LC_NUMERIC=C                          
[5] LC_TIME=English_United States.utf8    

time zone: America/La_Paz
tzcode source: internal

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
 [1] gt_0.10.1            xaringanthemer_0.4.2 epikit_0.1.6         flextable_0.9.4      janitor_2.2.0       
 [6] fabricatr_1.0.2      here_1.0.1           renderthis_0.2.1     lubridate_1.9.3      forcats_1.0.0       
[11] stringr_1.5.1        dplyr_1.1.4          purrr_1.0.2          readr_2.1.5          tidyr_1.3.1         
[16] tibble_3.2.1         ggplot2_3.5.0        tidyverse_2.0.0     

loaded via a namespace (and not attached):
 [1] tidyselect_1.2.0        farver_2.1.1            fastmap_1.1.1           xaringan_0.29          
 [5] fontquiver_0.2.1        pacman_0.5.1            promises_1.2.1          digest_0.6.34          
 [9] timechange_0.3.0        mime_0.12               lifecycle_1.0.4         sf_1.0-15              
[13] gfonts_0.2.0            ellipsis_0.3.2          magrittr_2.0.3          compiler_4.3.1         
[17] rlang_1.1.3             sass_0.4.8              tools_4.3.1             utf8_1.2.4             
[21] yaml_2.3.8              data.table_1.15.2       knitr_1.45              labeling_0.4.3         
[25] askpass_1.2.0           classInt_0.4-10         curl_5.2.1              showtextdb_3.0         
[29] xml2_1.3.6              KernSmooth_2.23-21      httpcode_0.3.0          withr_3.0.0            
[33] grid_4.3.1              fansi_1.0.6             sysfonts_0.8.9          gdtools_0.3.6          
[37] xtable_1.8-4            e1071_1.7-14            colorspace_2.1-0        scales_1.3.0           
[41] crul_1.4.0              cli_3.6.2               rmarkdown_2.25          crayon_1.5.2           
[45] remotes_2.4.2.1         ragg_1.2.7              generics_0.1.3          rstudioapi_0.15.0      
[49] tzdb_0.4.0              proxy_0.4-27            DBI_1.2.2               cachem_1.0.8           
[53] vctrs_0.6.5             jsonlite_1.8.8          fontBitstreamVera_0.1.1 hms_1.1.3              
[57] systemfonts_1.0.5       jquerylib_0.1.4         units_0.8-5             glue_1.7.0             
[61] stringi_1.8.3           gtable_0.3.4            later_1.3.2             munsell_0.5.0          
[65] pillar_1.9.0            htmltools_0.5.7         showtext_0.9-7          openssl_2.1.1          
[69] R6_2.5.1                textshaping_0.3.7       rprojroot_2.0.4         evaluate_0.23          
[73] shiny_1.8.0             highr_0.10              snakecase_0.11.1        fontLiberation_0.1.0   
[77] httpuv_1.6.14           bslib_0.6.1             class_7.3-22            Rcpp_1.0.12            
[81] zip_2.3.1               uuid_1.2-0              whisker_0.4.1           officer_0.6.5          
[85] xfun_0.42               fs_1.6.3                pkgconfig_2.0.3
3 Likes

Nice !