MPH Biostats – Week 2: R Markdown & Quarto in Posit Cloud

Author

Prepared for MPH Students

Published

September 29, 2025

Overview

This Week 2 lesson introduces R Markdown (.Rmd) and Quarto (.qmd) for creating reproducible public health reports in Posit Cloud. You’ll learn how to combine narrative, R code, and results into a single document you can render to HTML, PDF, or Word.

Learning objectives

  • Explain why R Markdown and Quarto support reproducible public health workflows.
  • Create and render a Quarto document in Posit Cloud.
  • Add Markdown text, R code chunks, and plots to a document.
  • Render to HTML, PDF, and Word for distribution to non-technical partners.

Setup (Posit Cloud)

  1. In your project, go to File ▶ New File ▶ Quarto Document… and choose HTML format.
  2. A starter document opens with a YAML header, sample text, and a code chunk.
  3. Click Render to compile the document.
  4. If a package is missing, install it in the Console: e.g., install.packages("openintro") and re-render.

Tip: Use the Visual editor (toggle at the top right) to edit headings, lists, and tables more easily.

R Markdown vs. Quarto (what & why)

  • R Markdown (.Rmd): The classic format for weaving text + R code + output in one file.
  • Quarto (.qmd): The modern successor—supports R, Python, Julia, Observable, better project features, and simpler configuration.

Typical headers

Quarto (.qmd)

---
title: "Obesity Disparities in St. Clair County: 2018-2023, Trends by Sex and SES"
author: "Jocelyn Wegienka"
date: "2025-09-29"
format: html
---

R Markdown (.Rmd)

---
title: "Obesity Disparities in St. Clair County: 2018-2023, Trends by Sex and SES"
author: "Jocelyn Wegienka"
date: "2025-09-29"
output: html_document
---

Public health use case: Generate a weekly surveillance brief where plots and indicators update automatically when the data change.

Markdown basics for narrative

Write text with simple markup: - #/##/### for headings - **bold**, *italics* - Lists: - item - Links: [MDHHS](https://www.michigan.gov/mdhhs) (links work best in HTML/PDF)

Example narrative block:

## Executive Summary
This brief report outlines adult obesity trends in **St. Clair County (2018–2023)**, with a focus on differences by **sex** and socioeconomic status **SES**. The data highlights notable disparities in obesity rates, revealing persistent or widening gaps across both demographic factors. Trends indicate that individuals with lower SES experienced higher and more sustained obesity rates compared to those with higher SES. Additionally, differences between male and female obesity prevalence suggest varying risk factors and potential areas for targeted intervention.

Code chunks (R)

Insert an R code chunk with the toolbar or type:

```{r}
# code here
```

Common chunk options (inside the chunk header): - echo: false – hide the code, show results - warning: false, message: false – suppress messages - fig-height, fig-width – figure sizing

Example:

```{r}
#| echo: true
#| warning: false
1 + 1
```

Public health example: simple obesity trend

Below we simulate adult obesity prevalence for a county public health brief and make a plot suitable for a board packet.

Code
library(ggplot2)

obesity1 <- data.frame(
  year = 2018:2023,
  prevalence = c(26.4, 33.0, 32.4, 36, 34.5, 34.2)
)

obesity1 <- read.csv("obesity_data.csv")

library(ggplot2)

hsb2 <- data.frame(
  year = 2018:2023,
  prevalence = c(28, 30.0, 32.4, 38, 33.5, 34.2)
)

Practice: Replace the values with your local data (e.g., from BRFSS or your county dashboard) and re-render.

Public health example: hsb2 mini-exercise

Use openintro::hsb2 to demonstrate categorical summaries and a simple chart (pretend race is a proxy for a categorical stratifier in a public report).

Code
# install.packages("openintro::hsb2")  # run once in Console if needed
library(openintro)
data("hsb2")

# quick look
head(hsb2)
# A tibble: 6 × 11
     id gender race  ses    schtyp prog        read write  math science socst
  <int> <chr>  <chr> <fct>  <fct>  <fct>      <int> <int> <int>   <int> <int>
1    70 male   white low    public general       57    52    41      47    57
2   121 female white middle public vocational    68    59    53      63    61
3    86 male   white high   public general       44    33    54      58    31
4   141 male   white high   public vocational    63    44    47      53    56
5   172 male   white middle public academic      47    52    57      53    61
6   113 male   white middle public academic      44    52    51      63    61
Code
# bar chart of race (counts)
ggplot(hsb2, aes(x = factor(race))) +
  geom_bar() +
  labs(title = "Number of Students by Race (hsb2)",
       x = "Race", y = "Count") +
  theme_minimal()

Code
hsb2 
# A tibble: 200 × 11
      id gender race          ses   schtyp prog   read write  math science socst
   <int> <chr>  <chr>         <fct> <fct>  <fct> <int> <int> <int>   <int> <int>
 1    70 male   white         low   public gene…    57    52    41      47    57
 2   121 female white         midd… public voca…    68    59    53      63    61
 3    86 male   white         high  public gene…    44    33    54      58    31
 4   141 male   white         high  public voca…    63    44    47      53    56
 5   172 male   white         midd… public acad…    47    52    57      53    61
 6   113 male   white         midd… public acad…    44    52    51      63    61
 7    50 male   african amer… midd… public gene…    50    59    42      53    61
 8    11 male   hispanic      midd… public acad…    34    46    45      39    36
 9    84 male   white         midd… public gene…    63    57    54      58    51
10    48 male   african amer… midd… public acad…    57    55    52      50    51
# ℹ 190 more rows
Code
library(ggplot2)

# Boxplot of math scores by gender
ggplot(hsb2, aes(x = factor(gender), y = math)) +
  geom_boxplot(fill = "#4C9F70") +
  labs(title = "Math Scores by Gender (hsb2)",
       x = "Gender",
       y = "Math Score") +
  theme_minimal()

Rendering to HTML, PDF, and Word

Control outputs in the YAML header:

---
format:
  html:
    toc: true
  pdf: default
  docx: default
---
  • HTML: best for interactive viewing and clickable links.
  • PDF: best for fixed-layout printing and formal submissions.
  • Word (.docx): best when collaborators will edit or track changes.

In public health agencies, Word/PDF are common deliverables for partners and leadership.

Reproducibility practices (public health friendly)

  • Keep code with the analysis: narrative + code + figures in one file.
  • Use relative paths and keep data files in a data/ folder.
  • Document assumptions and methods in a “Methods & Caveats” section.
  • Freeze package versions with renv for stable results over time.
  • Set seeds for simulations: set.seed(123).

Methods & Caveats (template)

## Methods & Caveats
Data source: BRFSS 2018–2023 county estimates (accessed YYYY-MM-DD).  
Prevalence calculated as weighted percent of adults with BMI ≥ 30.  
Estimates may be unstable (wide CIs) for small subgroups or years with limited sample sizes.

Hands-on practice

  1. Title & metadata: Edit the YAML to use your name and a project-appropriate title.
  2. Narrative: Write a 3–4 sentence Executive Summary for a public health director.
  3. Figure: Recreate the obesity plot with your own numbers; add a caption beneath it.
  4. Second figure: Use hsb2 to make a boxplot of math by gender with ggplot2.
  5. Export: Render to Word and PDF; check that headings, captions, and alt-text read well.
  6. Bonus: Hide the code in your final deliverable (echo: false) and keep a separate “analysis” version with code visible.

Stretch challenge (optional)

  • Add an inline result in your narrative (Quarto example): (remove the spaces around the backticks).
  • Create a small table summarizing prevalence by year with knitr::kable().
  • Add a Parameters section in YAML and make your document parametrized (e.g., county name, years).

Troubleshooting checklist

  • Render fails → Check that required packages are installed (Console: install.packages("pkg")).
  • Plots too small → Set fig-width / fig-height in the chunk options.
  • PDF won’t render → Ensure TinyTeX/LaTeX is available; otherwise use HTML/Word.
  • Slow renders → Cache expensive chunks with #| cache: true.

What to submit

  • Your rendered HTML (or PDF/Word) file.
  • Your .qmd source file.
  • A short paragraph (3–4 sentences) on how reproducible documents help public health in your setting.

End of Week 2 lesson. Great work!