class: center, middle, inverse, title-slide .title[ # Introduction to R for
Applied Epidemiology ] .subtitle[ ## Routine reports with {rmarkdown} ] .date[ ###
contact@appliedepi.org
] --- <style type="text/css"> .remark-code { font-size: 70%; } .remark-slide table{ border: none } .remark-slide-table { } tr:first-child { border-top: none; } tr:last-child { border-bottom: none; } </style> # Today: objectives & schedule * Understand R markdown as a tool to make routine reports * Explore the variety of formats and integrations for R markdown reports * Convert your Ebola case study code into an R markdown report * Make the R Markdown script dynamically conducive to data updates <div class="tabwid"><style>.cl-c55da3ee{}.cl-c559e9b6{font-family:'Helvetica';font-size:11pt;font-weight:normal;font-style:normal;text-decoration:none;color:rgba(0, 0, 0, 1.00);background-color:transparent;}.cl-c55b784e{margin:0;text-align:left;border-bottom: 0 solid rgba(0, 0, 0, 1.00);border-top: 0 solid rgba(0, 0, 0, 1.00);border-left: 0 solid rgba(0, 0, 0, 1.00);border-right: 0 solid rgba(0, 0, 0, 1.00);padding-bottom:5pt;padding-top:5pt;padding-left:5pt;padding-right:5pt;line-height: 1;background-color:transparent;}.cl-c55b88fc{width:1.033in;background-color:transparent;vertical-align: middle;border-bottom: 1.5pt solid rgba(102, 102, 102, 1.00);border-top: 1.5pt solid rgba(102, 102, 102, 1.00);border-left: 0 solid rgba(0, 0, 0, 1.00);border-right: 0 solid rgba(0, 0, 0, 1.00);margin-bottom:0;margin-top:0;margin-left:0;margin-right:0;}.cl-c55b8910{width:2.731in;background-color:transparent;vertical-align: middle;border-bottom: 1.5pt solid rgba(102, 102, 102, 1.00);border-top: 1.5pt solid rgba(102, 102, 102, 1.00);border-left: 0 solid rgba(0, 0, 0, 1.00);border-right: 0 solid rgba(0, 0, 0, 1.00);margin-bottom:0;margin-top:0;margin-left:0;margin-right:0;}.cl-c55b8924{width:1.033in;background-color:transparent;vertical-align: middle;border-bottom: 0 solid rgba(0, 0, 0, 1.00);border-top: 0 solid rgba(0, 0, 0, 1.00);border-left: 0 solid rgba(0, 0, 0, 1.00);border-right: 0 solid rgba(0, 0, 0, 1.00);margin-bottom:0;margin-top:0;margin-left:0;margin-right:0;}.cl-c55b892e{width:2.731in;background-color:transparent;vertical-align: middle;border-bottom: 0 solid rgba(0, 0, 0, 1.00);border-top: 0 solid rgba(0, 0, 0, 1.00);border-left: 0 solid rgba(0, 0, 0, 1.00);border-right: 0 solid rgba(0, 0, 0, 1.00);margin-bottom:0;margin-top:0;margin-left:0;margin-right:0;}.cl-c55b8938{width:1.033in;background-color:transparent;vertical-align: middle;border-bottom: 0 solid rgba(0, 0, 0, 1.00);border-top: 0 solid rgba(0, 0, 0, 1.00);border-left: 0 solid rgba(0, 0, 0, 1.00);border-right: 0 solid rgba(0, 0, 0, 1.00);margin-bottom:0;margin-top:0;margin-left:0;margin-right:0;}.cl-c55b8942{width:2.731in;background-color:transparent;vertical-align: middle;border-bottom: 0 solid rgba(0, 0, 0, 1.00);border-top: 0 solid rgba(0, 0, 0, 1.00);border-left: 0 solid rgba(0, 0, 0, 1.00);border-right: 0 solid rgba(0, 0, 0, 1.00);margin-bottom:0;margin-top:0;margin-left:0;margin-right:0;}.cl-c55b8956{width:1.033in;background-color:transparent;vertical-align: middle;border-bottom: 1.5pt solid rgba(102, 102, 102, 1.00);border-top: 0 solid rgba(0, 0, 0, 1.00);border-left: 0 solid rgba(0, 0, 0, 1.00);border-right: 0 solid rgba(0, 0, 0, 1.00);margin-bottom:0;margin-top:0;margin-left:0;margin-right:0;}.cl-c55b8960{width:2.731in;background-color:transparent;vertical-align: middle;border-bottom: 1.5pt solid rgba(102, 102, 102, 1.00);border-top: 0 solid rgba(0, 0, 0, 1.00);border-left: 0 solid rgba(0, 0, 0, 1.00);border-right: 0 solid rgba(0, 0, 0, 1.00);margin-bottom:0;margin-top:0;margin-left:0;margin-right:0;}.cl-c55b896a{width:1.033in;background-color:transparent;vertical-align: middle;border-bottom: 0 solid rgba(255, 255, 255, 0.00);border-top: 0 solid rgba(255, 255, 255, 0.00);border-left: 0 solid rgba(255, 255, 255, 0.00);border-right: 0 solid rgba(255, 255, 255, 0.00);margin-bottom:0;margin-top:0;margin-left:0;margin-right:0;}.cl-c55b897e{width:2.731in;background-color:transparent;vertical-align: middle;border-bottom: 0 solid rgba(255, 255, 255, 0.00);border-top: 0 solid rgba(255, 255, 255, 0.00);border-left: 0 solid rgba(255, 255, 255, 0.00);border-right: 0 solid rgba(255, 255, 255, 0.00);margin-bottom:0;margin-top:0;margin-left:0;margin-right:0;}</style><table data-quarto-disable-processing='true' class='cl-c55da3ee'><thead><tr style="overflow-wrap:break-word;"><th class="cl-c55b88fc"><p class="cl-c55b784e"><span class="cl-c559e9b6">Time</span></p></th><th class="cl-c55b8910"><p class="cl-c55b784e"><span class="cl-c559e9b6">Topic</span></p></th></tr></thead><tbody><tr style="overflow-wrap:break-word;"><td class="cl-c55b8924"><p class="cl-c55b784e"><span class="cl-c559e9b6">30 minutes</span></p></td><td class="cl-c55b892e"><p class="cl-c55b784e"><span class="cl-c559e9b6">R markdown slides & demonstration</span></p></td></tr><tr style="overflow-wrap:break-word;"><td class="cl-c55b8938"><p class="cl-c55b784e"><span class="cl-c559e9b6">2.5 hours</span></p></td><td class="cl-c55b8942"><p class="cl-c55b784e"><span class="cl-c559e9b6">Create your Ebola situation report</span></p></td></tr><tr style="overflow-wrap:break-word;"><td class="cl-c55b8956"><p class="cl-c55b784e"><span class="cl-c559e9b6">30 minutes</span></p></td><td class="cl-c55b8960"><p class="cl-c55b784e"><span class="cl-c559e9b6">Debrief</span></p></td></tr></tbody><tfoot><tr style="overflow-wrap:break-word;"><td colspan="2"class="cl-c55b896a"><p class="cl-c55b784e"><span class="cl-c559e9b6">Take breaks as you wish during the exercise</span></p></td></tr></tfoot></table></div> --- # Public health and routine reports: a love story .pull-left[ In public health we love our reports. - Outbreak situation reports - Weekly slide decks - Executive briefings - Public-facing reports - Community health surveys - Vaccination survey analyses - ... **Manual production is laborious and prone to human error** ] .pull-right[ <img src="../../images/welcome/automated_reports.png" width="100%" /> ] --- # Public health and routine reports: a love story .pull-left[ We often have to produce them for many sub-populations: - Neighborhood, postal code - County, district, province, state, country - Ethnic or occupational sub-populations - High-risk groups - Weekly, quarterly, annually **Manual production is laborious and prone to human error** ] .pull-right[ <img src="../../images/welcome/automated_reports.png" width="100%" /> ] --- # "Automation" v. the human eye .pull-left[ "Machine learning" and "AI" are hot topics right now. But in most public health and applied epidemiology scenarios, correct interpretation of trends also requires: - Experience - Local contextual knowledge - Grasp of the data flow and limitations How have you experienced the limitations of "automation" in your work? ] .pull-right[ <img src="../../images/rmarkdown/human_robot.png" width="75%" /> ] --- class: inverse, center, middle # R markdown ## A place for data-based writing</br>Code, text, and outputs together --- # Various outputs <img src="../../images/rmarkdown/rmarkdown_overview.png" width="100%" /> --- # Dashboards {rmarkdown} can produce simple dashboards to be emailed or hosted online. <img src="../../images/rmarkdown/flexdashboard_output.png" width="68%" /> .footnote[Enroll in our Advanced R Markdown course or see the [Epi R Handbook chapter](https://epirhandbook.com/en/new_pages/flexdashboard.html)!] --- class: inverse, center, middle # Even these slides were made with R Markdown! <img src="../../images/rmarkdown/even_slides.png" width="75%" /> .footnote[See the {xaringan} package; and enroll in our advanced R Markdown course!] --- # Overview **The entire script is now a document** that integrates **text sentences** with related **R code** and its **outputs**. Everything is updated when the script is run. <img src="../../images/rmd_1/rmarkdown_translation.png" width="100%" /> --- # Vocabulary - **Markdown (.md)** - a “language” not specific to R, that allows your plain text to be converted to html and other formats -- - **R Markdown (.Rmd)** - a variation on markdown that is specific to R -- - **{rmarkdown}** an R package used to render the markdown (text) in the R markdown file into the desired output -- - **{knitr}** - an R package that reads R code chunks and ‘knits’ them into the document -- - **Pandoc** - a separate software (but bundled with RStudio) that converts the output into word/pdf/powerpoint etc. <img src="../../images/rmarkdown/0_rmd.png" width="75%" /> .footnote[Image [source](https://rmarkdown.rstudio.com/authoring_quick_tour.html)] ??? This process happens in the background, so you do not need to know all these steps. However you may encounter these names. The .Rmd file is fed to knitr, which executes the R code chunks and creates a new .md (markdown) file which includes the R code and its rendered output. The .md file is then processed by pandoc to create the finished product: a Microsoft Word document, HTML file, powerpoint document, pdf, etc. --- class: center, middle # R code chunks --- # Code chunks In R Markdown, your code sits in "chunks" - tiny pieces of R script within the document. Mak chunks for discrete tasks (e.g. load packages, import data, data cleaning) .pull-left[ Parts of a code chunk: * 3 "backticks" and `{r}` start the chunk * **R code in the middle** * 3 backticks close the chunk *Keyboard shortcut: Ctrl + Alt + i* *Menu shortcut: Code -> Insert Chunk* ] .pull-right[ ````r ```{r} R code will be here ``` ```` </br> ````r ```{r} More R code will be here. ``` ```` ] --- # Normal R script (.R) <img src="../../images/rmarkdown/r_script.png" width="100%" /> --- # R Markdown code chunks (.Rmd) <img src="../../images/rmarkdown/rmd_script.png" width="100%" /> --- # The report output <img src="../../images/rmarkdown/word_simple.png" width="100%" /> --- class: inverse, center, middle # Text --- # Text <img src="../../images/rmarkdown/rmd_text.png" width="100%" /> --- # Text .panelset[ .panel[.panel-name[To get this] A normal text sentence. *Here is some text to be italicized* **Here is some text to be written in bold** * Bullet point 1 * Bullet point 2 ] .panel[.panel-name[Type this] A normal text sentence. `*Here is some text to be italicized*` `**Here is some text to be written in bold**` `* Bullet point 1` `* Bullet point 2` ] ] .footnote[See more RMarkdown formatting [here](https://rmarkdown.rstudio.com/authoring_basics.html)] --- # Report headings and sections .panelset[ .panel[.panel-name[To get this] # Big heading ## Smaller headings ### Smaller headings #### Even smaller headings ] .panel[.panel-name[Type this] `# Big heading` `## Smaller headings` `### Smaller headings` `#### Even smaller headings` ] ] --- # Add text to the report <img src="../../images/rmarkdown/word_text.png" width="100%" /> --- class: inverse, center, middle # Settings --- # YAML settings This section at the **top of the document** specifies core settings for the production. Settings are written in `key: value` pairs. ```{results='asis'} --- title: "Ebola Outbreak Situation Report" author: "Neale Batra" output: word_document date: "2025-12-02" --- ``` ??? Note that it starts and ends with three dashes, and that placement of spaces and colons are very important --- # The "setup" chunk **Chunk "options"** adjust how R code and its outputs are displayed in the report. The `setup` chunk near top of the R Markdown uses a {knitr} function to set the **default** "options" for all chunks. * Run chunks: `eval = TRUE` * Show the code in the report: `echo = TRUE` * Show warnings in the report: `warning = TRUE` * Show errors in the report: `error = TRUE` * Show output in the report: `include = TRUE` Below, the default is set so that R code is printed in the report, but warnings and error messages are not. ````r ```{r setup, include=FALSE} knitr::opts_chunk$set(echo = TRUE, warning = FALSE, error = FALSE) ``` ```` --- # Chunk options To override the defaults, you can adjust each chunk's options: .pull-left[ Adjust chunk "options" inside the `{r}` * Run the chunk: `eval = TRUE` * Show the code: `echo = TRUE` * Show warnings: `warning = TRUE` * Show errors: `error = TRUE` * Show output: `include = TRUE` Note the commas between each option. ] .pull-right[ ````r ```{r packages, echo = FALSE, warning = FALSE} pacman::p_load( rio, # import/export here, # file paths janitor, # cleaning & simple tables tidyverse # data management & viz ) ``` ```` ] Learn more about code chunk options [here](https://rmarkdown.rstudio.com/lesson-3.html) ??? Chunk names cannot contain spaces --- # Running the document Press the "knit" button at the top. Use the drop-down for options. <img src="../../images/rmarkdown/4_knitbutton.PNG" width="10%" /> Progress will show in the "R Markdown" pane (next to the R Console) <img src="../../images/rmarkdown/4_progress.png" width="100%" /> The output will save next to your .Rmd file by default. ??? Please see the Handbook for options to create a "Report factory" where it becomes easier to catalog outputs from many different reports in date- and time-stamped folders. --- class: inverse, center, middle # Live demonstration <img src="../../images/functions_packages/piano_man.jpg" width="50%" /> --- class: inverse, center, middle # More advanced tips --- # Inline R code This written inline code and text: <img src="../../images/rmarkdown/verbatim_inline_1_1_en.png" width="80%" /> produces this: <img src="../../images/rmarkdown/verbatim_inline_1_2_en.png" width="80%" /> --- # Inline R code This written inline code and text: <img src="../../images/rmarkdown/verbatim_inline_2_1_en.png" width="90%" /> produces this: <img src="../../images/rmarkdown/verbatim_inline_2_2_en.png" width="80%" /> --- # Helper functions {epikit} ``` r epikit::fmt_count(surv, is.na(date_onset)) ``` ``` ## [1] "33 (5.2%)" ``` ``` r str_glue("{fmt_count(surv, is.na(date_onset))} are missing date of onset and not shown.") ``` ``` ## 33 (5.2%) are missing date of onset and not shown. ``` -- {scales} ``` r str_glue("There were {comma(sum(as.numeric(surv$diff), na.rm=T))} total delay days between symptom onset and report.") ``` ``` ## There were 1,826 total delay days between symptom onset and report. ``` --- # Static tables This written in your R markdown: ````` Column 1 |Column 2 |Column 3 ---------|----------|-------- Cell A |Cell B |Cell C Cell D |Cell E |Cell F ````` produces this: Column 1 |Column 2 |Column 3 ---------|----------|-------- Cell A |Cell B |Cell C Cell D |Cell E |Cell F Dynamic tables can be created with packages like {flextable} and {DT}. --- # Source mode Your script may come to look like this: <img src="../../images/rmarkdown/source_mode_en.png" width="70%" /> --- # Visual mode RStudio allows you to edit in "Visual Mode" which looks like a Word document <img src="../../images/rmarkdown/visual_mode_en.png" width="70%" /> ??? If writing the document in code is intimidating, RStudio allows you to toggle the script into "Visual Mode", so that your document looks similar to a Word document. --- # `params` In the YAML, you can define `params` to be available to the report: ```{results='asis'} --- title: "Surveillance report" output: html_document params: date: "2021-04-10" hospital: "Central Hospital" --- ``` You can create the names for these params --- # `params` In the R Markdown, call these `params` values in your code using: `params$` <img src="../../images/rmarkdown/5_parameterized_1.png" width="70%" /> --- # `params` In the R Markdown, call these `params` values in your code using: `params$` <img src="../../images/rmarkdown/5_parameterized_2.png" width="70%" /> --- # `params` In the R Markdown, call these `params` values in your code using: `params$` <img src="../../images/rmarkdown/5_parameterized_3.png" width="70%" /> --- # `params` .pull-left[ <img src="../../images/rmarkdown/5_parameterized_menu_1.png" width="100%" /> ] .pull-right[ <img src="../../images/rmarkdown/5_parameterized_menu_2.png" width="100%" /> ] --- # Report templates You can provide R Markdown with Word or PPT templates (e.g. with logos, etc.) Once the report is rendered, you can edit the text to add interpretations. Applied Epi works with Doctors without Borders (MSF) to offer R Markdown templates for situation reports: - Cholera/acute watery diarrhoea - Meningitis - Measles/Rubella - Acute Jaundice Syndrome (often suspected to be Hepatitis E) and for survey analysis: - Retrospective mortality and access to care - Vaccination coverage - Malnutrition --- # Breakouts <!-- --- --> <!-- # inline R code --> <!-- As of --> <!-- `` `r format(Sys.Date())` ``, there were --> <!-- `` `r nrow(surv)` `` confirmed cases. --> <!-- As of --> <!-- `` `r format(Sys.Date(), '%d %B, %Y')` ``, there were --> <!-- `` `r nrow(surv)` `` confirmed cases. --> <!-- Produces this: --> <!-- As of 02 December, 2025, there were 636 confirmed cases. --> <!-- --- -->