Introduction to Quarto
University of Kansas Medical Center
July 29, 2026
By the end of today’s session, you should be able to:
R4DS Chapters 28-29
| Chapter | Focus |
|---|---|
| 28 | Building reproducible Quarto documents |
| 29 | Creating different outputs and formats |
What is Quarto? A publishing system for creating reproducible documents by combining code, text, and visualizations.
Every Quarto document contains four building blocks:
Note
Think of Quarto as a recipe:
Quarto provides two ways to edit your documents: the Visual Editor for a word processor-like experience and the Source Editor for writing directly in Markdown. Both produce the same final document, so you can choose the workflow that best fits your needs.
Source
## Text formatting
*italic* **bold** ~~strikeout~~ `code`
superscript^2^ subscript~2~
[underline]{.underline} [small caps]{.smallcaps}
## Headings
# 1st Level Header
## 2nd Level Header
### 3rd Level Header
## Lists
- Bulleted list item 1
- Item 2
- Item 2a
- Item 2b
1. Numbered list item 1
2. Item 2.
The numbers are incremented automatically in the output.
## Links and images
<http://example.com>
[linked phrase](http://example.com)
{fig-alt="Quarto logo and the word quarto spelled in small case letters"}
## Tables
| First Header | Second Header |
|--------------|---------------|
| Content Cell | Content Cell |
| Content Cell | Content Cell |The visual editor is designed for users who prefer a graphical interface, making it easier to format documents, insert code, and create polished reports without needing to write all Markdown syntax manually.
Visual
Both Markdown and HTML can be used to format Quarto documents. Markdown is the preferred syntax for most writing tasks because it is concise, readable, and easy to maintain. HTML is available when you need additional formatting or customization.
| Feature | Markdown | HTML |
|---|---|---|
| Bold | **text** |
<strong>text</strong> |
| Italic | *text* |
<em>text</em> |
| Heading | ## Heading |
<h2>Heading</h2> |
| Bullet List | - Item |
<ul><li>Item</li></ul> |
| Numbered List | 1. Item |
<ol><li>Item</li></ol> |
| Link | [Posit](https://posit.co) |
<a href="https://posit.co">Posit</a> |
| Image |  |
<img src="logo.png"> |
Example: Custom HTML Styling
Markdown cannot easily apply custom colors or styles, but HTML can.
Hadley’s Philosophy
Use Markdown for almost everything. It is easier to read, write, and collaborate on.
Use HTML only when you need formatting that Markdown doesn’t support, such as custom styling, colors, layouts, or embedded web content.
Take-Home Message
You do not need to learn HTML to be productive in Quarto. Markdown covers the vast majority of everyday writing tasks, while HTML is there when you need more control over the appearance of your document.
Code chunks execute your analysis and insert the results directly into your document. Chunk labels and options help organize your work while controlling what appears in the final output.
Give chunks meaningful names so they are easier to identify, troubleshoot, and reference.
Chunk options control what your audience sees, not what your code does.
| Option | Purpose |
|---|---|
echo: false |
Hide code, show output |
eval: false |
Show code, don’t run it |
warning: false |
Hide warnings |
message: false |
Hide package startup messages |
Tip
Remember:
echo controls whether the code is displayed.eval controls whether the code is executed.These options can be combined. For example, echo: true with eval: false displays the code without running it, while echo: false with eval: true runs the code but only displays the results.
Set default chunk behavior once using global execution options in the YAML header.
Note
Chunk options apply to a single chunk, while global options become the default for every chunk in your document.
Quarto automatically creates publication-ready figures and tables directly from your analysis. Update your code, render the document, and every result stays synchronized.
Display Code Only
eval: false displays the code without running it.
Display Figure
echo: false hides the code and displays only the figure.
Tables in Quarto
Quarto supports several table packages depending on your desired output. Here are two of the most commonly used.
gt
Source
Output
| mpg | cyl | disp | hp | drat | wt | qsec | vs | am | gear | carb |
|---|---|---|---|---|---|---|---|---|---|---|
| 21.0 | 6 | 160 | 110 | 3.90 | 2.620 | 16.46 | 0 | 1 | 4 | 4 |
| 21.0 | 6 | 160 | 110 | 3.90 | 2.875 | 17.02 | 0 | 1 | 4 | 4 |
| 22.8 | 4 | 108 | 93 | 3.85 | 2.320 | 18.61 | 1 | 1 | 4 | 1 |
| 21.4 | 6 | 258 | 110 | 3.08 | 3.215 | 19.44 | 1 | 0 | 3 | 1 |
| 18.7 | 8 | 360 | 175 | 3.15 | 3.440 | 17.02 | 0 | 0 | 3 | 2 |
| 18.1 | 6 | 225 | 105 | 2.76 | 3.460 | 20.22 | 1 | 0 | 3 | 1 |
flextable
Source
Output
mpg | cyl | disp | hp | drat | wt | qsec | vs | am | gear | carb |
|---|---|---|---|---|---|---|---|---|---|---|
21.0 | 6 | 160 | 110 | 3.90 | 2.620 | 16.46 | 0 | 1 | 4 | 4 |
21.0 | 6 | 160 | 110 | 3.90 | 2.875 | 17.02 | 0 | 1 | 4 | 4 |
22.8 | 4 | 108 | 93 | 3.85 | 2.320 | 18.61 | 1 | 1 | 4 | 1 |
21.4 | 6 | 258 | 110 | 3.08 | 3.215 | 19.44 | 1 | 0 | 3 | 1 |
18.7 | 8 | 360 | 175 | 3.15 | 3.440 | 17.02 | 0 | 0 | 3 | 2 |
18.1 | 6 | 225 | 105 | 2.76 | 3.460 | 20.22 | 1 | 0 | 3 | 1 |
Note
Choosing a table package
gt creates polished, publication-quality tables and works especially well for HTML reports.flextable is designed for Microsoft Word and PowerPoint, making it a great choice for collaborators and manuscripts.YAML is the header section of a Quarto document that provides instructions for how your document should be created and formatted.
Think of YAML as the configuration file for your document.
YAML can:
Example:
Note
YAML is processed before your R code runs. It tells Quarto how to build your final document.
Quarto provides multiple ways to customize your documents beyond the default settings.
| Tool | Purpose | Example Uses |
|---|---|---|
| Quarto extensions | Add reusable functionality | templates, themes, publishing workflows |
| CSS | Customize HTML appearance | colors, fonts, spacing, layouts |
| SCSS | Build advanced CSS styles | reusable style systems |
| Lua filters | Modify document behavior | custom formatting rules |
| LaTeX | Customize PDF output | manuscript formatting |
Tip
Most users will customize Quarto through YAML, themes, and CSS. Advanced tools like Lua filters and LaTeX provide additional control when needed.
YAML can connect your document to themes, stylesheets, and other custom resources.
Quarto extensions allow you to customize fonts, colors, spacing, page layout, and document branding to create a consistent look and feel across projects. Explore the quarto-kansas repository for an example of a custom Quarto extension.
Quarto can automatically manage citations and references using a bibliography file.
The bibliography is connected through the YAML header:
Adding Citations
Citations are added directly within the text using the author-year citation key.
Example:
Quarto automatically formats the citation:
Regular physical activity is associated with improved health outcomes (Piercy et al., 2018).
Reference List
At the end of the document, Quarto automatically generates:
from the entries stored in:
references.bib
Note
References are stored separately from the document content, making citations reusable and automatically updated across projects.
For a complete example of manuscript writing and citation management in Quarto, explore the quarto-manuscript template.
Most Quarto errors come from three places:
| Error Type | Common Errors | Check Here |
|---|---|---|
| R Code | Package not installed, object not found, syntax errors | Code chunk |
| Quarto / YAML | Incorrect indentation, missing :, invalid YAML options |
YAML header |
| Markdown | Unclosed code chunks, missing brackets, missing parentheses or quotation marks | Document text |
Tip
Debugging workflow
Quarto combines text, code, and results into reproducible documents.
Key Concepts
| Concept | Purpose |
|---|---|
| Quarto documents | Combine narrative, analysis, and outputs in one place |
| Markdown | Create readable, structured documents using simple syntax |
| Code chunks | Execute R code and insert results automatically |
| Chunk options | Control what code and output appear |
| Figures & tables | Generate reproducible, publication-ready outputs |
| YAML | Configure document settings and customization |
| Citations | Manage references automatically through bibliography files |
Tip
The Quarto workflow
Write → Analyze → Render → Communicate
When your data or code change, your document updates with them.
One Quarto document can be transformed into multiple output formats.
The content and analysis stay the same, while the final product changes based on the audience and purpose.
| Format | Best For | Example Uses |
|---|---|---|
| HTML | Interactive web documents | Reports, dashboards, online supplements |
| Fixed-layout documents | Manuscripts, formal reports | |
| DOCX | Editable documents | Collaborator drafts, reviews |
| Revealjs | HTML presentations | Research talks, workshops |
| PPTX | PowerPoint slides | Meetings, presentations |
Quarto can also create interactive applications using Shiny. Instead of a static report, interactive workflows allow user exploration.
Tip
Shiny allows users to interact with results without needing to write R code.
Quarto allows researchers to communicate the same work in different ways.
One Source → Many Outputs
A single .qmd file can become:
Note
The goal is not creating more documents.
The goal is creating one reproducible source that can be shared in many formats.
A reproducible workflow requires more than code.
✓ Render often
✓ Keep files organized
✓ Write narrative alongside analysis
✓ Document decisions
✓ Use meaningful chunk labels
✓ Save source files with projects
✓ Embrace reproducibility
Chapter 28: Quarto
Quarto brings together:
Key idea:
A Quarto document connects the analysis process with the final communication product.
Chapter 29: Quarto Formats
Quarto allows one source document to become many outputs:
Key idea:
Write once. Render many ways.
Tip
Quarto is not just a document creation tool. It is a reproducible workflow for communicating research.
🎉 Congratulations!
You’ve learned the foundations of Quarto.
Now let’s put it all together and build your own presentation! 🚀
Today you will combine the concepts from R4DS:
Import → Transform → Program → Visualize → Communicate
Your goal:
Tip
The goal is not just to make a plot.
The goal is to create a reproducible workflow that can be reused and shared.
Step 1: Navigate to the code folder under your name in the 2026-RLAB-Practical-Exercises folder.
Step 2: Create an _extensions folder and a rlab folder inside extensions.
Step 3: Create an _extensions.yml and custom.css file inside the rlab folder.
Step 4: Add the following yaml to _extensions.yml:
Step 5: Add the format and extension to the yaml of the communication.qmd file.
Step 6: Copy the CSS from this custom.css file into the custom.css file that you just created.
Step 7: Optional. Experiment with ths css styling in custom.css by changing the images, colors, font sizes, etc. to make it your own.
Import Data In this exercise, you will create an in-memory DuckDB database, copy the nycflights13 datasets into it, and use dplyr to create a new data frame for analysis.
Step 1:
Create an in-memory DuckDB database by:
Connecting to DuckDB with DBI::dbConnect(). Using “:memory:” as the database location. Copying the nycflights13 datasets into the database with dbplyr::copy_nycflights13(). con <- DBI::dbConnect(duckdb::duckdb(), dbdir = “:memory:”)
dbplyr::copy_nycflights13(con)
Step 2:
Using the tables stored in DuckDB, create a new object named flights that:
After completing these steps, the flights object should contain the selected weather variables along with the matching flight information, ready for use in later exercises.
Write Your Own Filter Function
Create a function named custom_filter() that filters a data frame based on a user-specified variable and value.
Your function should have three arguments:
Inside the function:
After writing your function, test it by creating a new object named filtered_flights that contains only rows where wind_speed is greater than or equal to 30 miles per hour.
If your function is written correctly, you should be able to call it by supplying a data frame, an unquoted variable name, and a comparison value.
Write Your Own Visualization Function
In this exercise, you will create a reusable function that produces a scatterplot using ggplot2. Your function should allow the user to choose the dataset, the variables to plot, and any optional arguments supported by ggplot2::geom_point().
Step 1:
Create a function named custom_visualization() with four arguments:
Step 2:
Before creating the plot, remove any rows where both the x and y variables are missing (NA).
Hint: The expression inside if_any() should refer to the range from xvar to yvar, and the predicate should be is.na.
Step 3:
Pipe the filtered data into ggplot2::ggplot().
Use ggplot2::aes() to map:
Step 4:
Add a scatterplot layer using ggplot2::geom_point().
Instead of specifying arguments like color or size yourself, forward all optional arguments using …. This allows users to customize the points by passing any arguments accepted by geom_point(), such as: color, size, shape, fill, alpha, stroke, etc.
Step 5:
Test your function using the filtered_flights data frame. Create a scatterplot of:
Customize the points by passing several optional arguments through …, for example:
color = “blue” size = 4 shape = 21 stroke = 2 fill = “red”
If your function is written correctly, these arguments should be passed automatically to ggplot2::geom_point() without modifying the function itself.
R for Lifestyle and Brain Health (R-LAB)