This tutorial introduces R Markdown and Quarto as tools for combining code, output, and narrative text in a single, dynamic, and fully reproducible document. Whether you are writing a corpus analysis report, a phonetics study, or a data science notebook, these tools allow you to weave together your R code, its output, and your prose explanation into a polished, shareable document.
The tutorial is aimed at beginners and intermediate R users in the humanities and social sciences. It covers the full workflow: understanding what R Markdown and Quarto are and how they differ, learning Markdown syntax, configuring YAML headers, controlling code chunk behaviour, producing multiple output formats, and using Quarto’s advanced features such as callout blocks, cross-references, citations, and project-level configuration.
By the end of this tutorial you will be able to:
Create a reproducible R Markdown or Quarto document from scratch
Write well-structured Markdown prose with headings, lists, tables, and figures
Control how code chunks are displayed and executed
Export your work as HTML, PDF, Word, or a presentation
Use Quarto-specific features: callouts, cross-references, freeze, and _quarto.yml
Manage citations and bibliographies with BibTeX
Prerequisite Knowledge
Before working through this tutorial, you should be familiar with:
Schweinberger, Martin. 2026. R Markdown and Quarto: Creating Reproducible Documents. Brisbane: The Language Technology and Data Analysis Laboratory (LADAL). url: https://ladal.edu.au/tutorials/notebooks/notebooks.html (Version 2026.03.10).
Setup
Installing Packages
Code
# Run once — comment out after installationinstall.packages("rmarkdown")install.packages("knitr")install.packages("tidyverse")install.packages("flextable")install.packages("kableExtra")install.packages("bookdown") # for cross-references in R Markdown# Quarto is installed separately from https://quarto.org/docs/get-started/
What you will learn: What R Markdown and Quarto are; why reproducible documents matter; and how these tools fit into a modern research workflow
The Problem They Solve
A typical research workflow involves several disconnected steps: running R code in a script, copying results into a Word document, inserting figures manually, and then updating everything again when the data changes. This workflow is fragile — a change in the data means re-running the code, re-copying the numbers, and re-inserting the figures, with every step introducing the risk of inconsistency.
R Markdown and Quarto solve this by integrating code, output, and prose in a single source document. When you render the document, the code runs, the output is inserted automatically, and the prose and results are always in sync. The document is reproducible: anyone with the source file and data can re-render it and obtain exactly the same output.
R Markdown
R Markdown was introduced by the knitr package (xie2015knitr?) and formalised in the rmarkdown package (allaire2023rmarkdown?). An R Markdown document (.Rmd) combines:
A YAML header specifying document metadata and output format
Markdown prose for narrative text
R code chunks that are executed when the document is rendered
R Markdown documents are rendered by knitr (which executes the R code and weaves the output into the document) followed by Pandoc (which converts the resulting Markdown into the target output format — HTML, PDF, Word, etc.).
Quarto
Quarto is the next-generation publishing system developed by Posit (formerly RStudio). A Quarto document (.qmd) uses the same Markdown + code chunk approach as R Markdown, but with several important advances:
Language-agnostic: supports R, Python, Julia, and Observable JS in the same document
Unified syntax: chunk options use #| comments rather than chunk header parameters
Richer output features: built-in callout blocks, cross-references, layouts, and theming
Project system:_quarto.yml configures entire websites, books, or presentations
Better defaults: produces cleaner HTML and PDF output out of the box
For new projects, Quarto is recommended. R Markdown remains fully supported and is still widely used. This tutorial covers both.
R Markdown vs. Quarto
Section Overview
What you will learn: How R Markdown and Quarto differ in syntax, features, and workflow; and when to use each
`` `r .QuartoInlineRender(expr)` `` or `` `r expr` ``
Freeze / caching
Via `knitr` cache
`freeze: auto` in `_quarto.yml`
Maintained by
Posit / community
Posit
When to use
Existing `.Rmd` projects; R-only workflows
New projects; multi-language; websites; books
Which Should I Use?
Use R Markdown if you are working on an existing .Rmd project, or if you need a package that is R Markdown-specific (e.g. blogdown, bookdown)
Use Quarto for all new projects — it is more powerful, better maintained, and handles multi-language workflows elegantly
Both render to the same output formats via Pandoc, so skills transfer directly between them
Creating Your First Document
Section Overview
What you will learn: How to create a new R Markdown or Quarto document in RStudio; what the basic structure looks like; and how to render it
In RStudio
R Markdown: Go to File → New File → R Markdown. Choose the output format (HTML is the default) and click OK. RStudio creates a template .Rmd file with a YAML header, some sample text, and a few code chunks.
Quarto: Go to File → New File → Quarto Document. Again choose your output format and click Create. RStudio creates a template .qmd file.
Basic Structure
Both document types share the same three-part structure:
---YAML header---Markdown prose` ``{r}# R code chunk` ``
Rendering
R Markdown: Click the Knit button in RStudio (or run rmarkdown::render("file.Rmd") in the console).
Quarto: Click the Render button in RStudio (or run quarto render file.qmd in the terminal).
Both processes: execute all code chunks → weave output into the document → convert to the target format via Pandoc.
Keyboard Shortcut
Ctrl+Shift+K (Windows/Linux) or Cmd+Shift+K (Mac) renders the current document in RStudio — for both R Markdown and Quarto.
YAML Headers
Section Overview
What you will learn: What YAML is; the most important YAML fields for R Markdown and Quarto; how to configure output formats, themes, and table of contents; and how Quarto’s YAML extends R Markdown’s
What Is YAML?
YAML (Yet Another Markup Language) is a human-readable data serialisation format used to store configuration. In R Markdown and Quarto, the YAML header sits between two sets of --- at the top of the document and controls metadata (title, author, date) and rendering options (output format, theme, table of contents).
YAML is indentation-sensitive — use spaces, not tabs, and be consistent with nesting.
title:"Corpus Frequency Analysis"author:"Martin Schweinberger"date:"YYYY-MM-DD # use Sys.Date() in practice"output:html_document:toc:truetoc_depth:3toc_float:truenumber_sections:truetheme: cosmohighlight: tangocode_folding: showdf_print: pagedbibliography: references.bibcsl: unified-style-linguistics.csl
How data frames are printed (`default`, `kable`, `tibble`, `paged`)
`bibliography`
Path to `.bib` bibliography file
`csl`
Citation style language file for reference formatting
`params`
Parameterised report inputs — see Parameterised Reports section
Quarto YAML
Quarto’s YAML uses nested format: keys rather than output:, and adds many new fields:
title:"Corpus Frequency Analysis"author:-name:"Martin Schweinberger"affiliation:"The University of Queensland"email:"m.schweinberger@uq.edu.au"date: last-modifieddate-format:"DD MMMM YYYY"format:html:toc:truetoc-depth:4toc-title:"Contents"toc-location: leftnumber-sections:truenumber-depth:3code-fold: showcode-tools:truecode-line-numbers:truetheme: cosmohighlight-style: tangoembed-resources:truesmooth-scroll:truecitations-hover:truefootnotes-hover:truepdf:documentclass: articlegeometry: margin=2.5cmtoc:truedocx:reference-doc: template.docxexecute:echo:truewarning:falsemessage:falsecache:falsebibliography: references.bibcsl: unified-style-linguistics.csllang: en-GB
Field
Description
`title`
Document title
`author`
Can be a list with `name`, `affiliation`, `email`, `orcid`
`date: last-modified`
Automatically set to the file's last-modified date
`date-format`
Date display format using `dayjs` tokens
`format: html:`
HTML output options — nested under `format: html:`
`toc-location`
Position of ToC: `left`, `right`, `body`
`code-fold`
Code folding: `show`, `hide`, `true`, `false`
`code-tools`
Show a toolbar to copy code or view source
`code-line-numbers`
Add line numbers to code blocks
`embed-resources`
Bundle all dependencies into a single self-contained HTML file
`smooth-scroll`
Enable smooth scrolling between sections
`citations-hover`
Show citation details on hover
`execute:`
Global chunk execution defaults — applies to all chunks
`execute: cache`
Cache all chunk outputs to speed up re-rendering
`lang`
Document language for hyphenation and accessibility
`bibliography`
Path to `.bib` file
`csl`
Citation style language file
Code Chunks
Section Overview
What you will learn: How to insert and label code chunks; how to control their execution, display, and output with chunk options; and how R Markdown and Quarto chunk syntax differ
Inserting a Code Chunk
Keyboard shortcut:Ctrl+Alt+I (Windows/Linux) or Cmd+Option+I (Mac) inserts a new code chunk in RStudio.
R Markdown syntax — options go in the chunk header:
Both syntaxes are valid in Quarto, but the #| style is preferred because it is language-agnostic (the same syntax works for Python, Julia, etc.) and keeps chunk options inside the chunk where they are easier to see.
Chunk Option Reference
Option
R Markdown
Quarto
Effect
`label`
`label`
`label`
Unique chunk identifier (required for cross-refs and caching)
`echo`
`echo`
`echo`
`true` show code; `false` hide code; `fenced` show with delimiters
`eval`
`eval`
`eval`
`true` run the chunk; `false` skip execution entirely
`include`
`include`
`include`
`false` run but suppress ALL output including code, results, messages
format:html:fig-height:5fig-width:7fig-align: center
Inline Code
Inline code embeds a computed value directly in prose without a separate code chunk:
R Markdown: write a backtick followed immediately by r, then a space, your expression, and a closing backtick — directly in prose. When rendered, the expression is replaced by its computed value — e.g. The corpus contains 4,572 tokens.
Quarto: the equivalent syntax is a backtick followed by {r}, a space, your expression, and a closing backtick — placed in prose. The older R Markdown syntax also works in Quarto.
Inline code is rendered inline — the expression is replaced with its value in the output. This ensures numbers in your prose always match your data.
Markdown Syntax Reference
Section Overview
What you will learn: The full Markdown syntax supported by R Markdown and Quarto, from basic formatting to advanced features like footnotes, math, diagrams, and HTML
Monophthong: A vowel with a single, stable tongue position during production.Diphthong: A vowel that involves a glide from one tongue position to another.Formant: A resonant frequency band produced by the vocal tract shape.
Monophthong
A vowel with a single, stable tongue position during production.
Diphthong
A vowel that involves a glide from one tongue position to another.
Formant
A resonant frequency band produced by the vocal tract shape.
Links
[LADAL](https://ladal.edu.au) # external link[Introduction](#intro) # internal anchor link[Schweinberger 2026](references.html#ref-sch26) # link to reference<m.schweinberger@uq.edu.au> # auto-linked email
| Left | Centre | Right ||:---------|:--------:|---------:|| text | text | 1,234 || text | text | 5,678 |
Left
Centre
Right
text
text
1,234
text
text
5,678
For production tables — sortable columns, striped rows, captions, cross-references — use flextable() or knitr::kable() in a code chunk rather than raw Markdown tables.
Footnotes
Formants are resonant frequencies of the vocal tract.[^1][^1]: For a thorough introduction to formant analysis see Johnson (2003).
Formants are resonant frequencies of the vocal tract.1
Inline footnotes (Quarto/Pandoc):
Formants are resonant frequencies of the vocal tract.^[For a thorough introduction see Johnson (2003).]
Quarto supports Mermaid diagrams natively with no extra packages:
```{mermaid}graph TD A[Raw audio] --> B[Praat formant extraction] B --> C[Tab-delimited .txt file] C --> D[Load in R] D --> E[Normalisation] E --> F[Vowel chart]```
graph TD
A[Raw audio] --> B[Praat formant extraction]
B --> C[Tab-delimited .txt file]
C --> D[Load in R]
D --> E[Normalisation]
E --> F[Vowel chart]
Other diagram types: flowchart, sequenceDiagram, gantt, classDiagram, stateDiagram, erDiagram, pie.
HTML Elements
Raw HTML passes through directly in both R Markdown and Quarto HTML output.
Expandable section:
<details> <summary>Click to expand: full model output</summary> Content hidden until expanded. Useful for supplementary material.</details>
Click to expand: full model output
Content hidden until expanded. Useful for supplementary material.
Press <kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>K</kbd> to render.
Press Ctrl+Shift+K to render.
Escaping Special Characters
Backslash escapes Markdown special characters:
\*not italic\*\`not code\`\# not a heading \[not a link\]
*not italic* · `not code` · # not a heading · [not a link]
Horizontal Rules
---***___
All three produce a horizontal rule:
Emojis
:smile: :+1: :sparkles: :books: :bar_chart:
:smile: :+1: :sparkles: :books: :bar_chart:
(Requires emoji extension or appropriate Pandoc version — works in Quarto HTML by default.)
Output Formats
Section Overview
What you will learn: How to render R Markdown and Quarto documents to HTML, PDF, Word, and presentation formats; what options are available for each; and how to choose the right format for your audience
HTML
HTML is the richest output format — it supports interactive widgets, floating tables of contents, collapsible code, hover citations, and smooth scrolling. It is the recommended format for sharing analysis online or via email.
format:html:toc:truetoc-location: lefttheme: cosmocode-fold: showembed-resources:true # self-contained single file
embed-resources: true
By default, Quarto HTML output references external libraries (Bootstrap, highlight.js, etc.) via relative paths. Setting embed-resources: true bundles everything into a single .html file — ideal for sharing by email or uploading to a repository without worrying about broken relative paths.
PDF
PDF output requires a LaTeX distribution. The recommended option is TinyTeX, which can be installed from R:
If your document contains IPA symbols, non-Latin scripts, or special characters, use latex_engine: xelatex (R Markdown) or latex-engine: xelatex (Quarto). The default pdflatex engine does not support Unicode. Also ensure your fonts support the required character ranges.
Word (.docx)
Word output is useful when collaborators need to add track-changes comments or when a journal requires .docx submission.
To create a Word template: render a document to .docx, open it in Word, modify the Heading 1, Body Text, Code, and Caption styles to match your requirements, save it, and point reference_docx/reference-doc at it.
Presentations
Quarto Reveal.js (HTML Slides)
Reveal.js is Quarto’s primary presentation format — fully interactive, browser-based slides:
format:revealjs:theme: simple # default, simple, sky, moon, serif, solarizedslide-number:truechalkboard:true # interactive drawing on slidesincremental:true # bullet points appear one at a timefooter:"LADAL — ladal.edu.au"logo: /images/uq1.jpgtransition: slide # none, fade, slide, convex, concave, zoombackground-transition: fade
In a Reveal.js document, each ## heading starts a new slide, and --- creates a slide without a heading. Columns are created with:
output:ioslides_presentation:widescreen:truesmaller:trueslidy_presentation:footer:"LADAL"beamer_presentation:theme: Madrid
Format
Best for
R Markdown
Quarto
HTML (`html_document`/`html`)
Online sharing; interactive outputs; most feature-rich
✓
✓
PDF (`pdf_document`/`pdf`)
Print; journal submission; formal reports
✓
✓
Word (`word_document`/`docx`)
Collaboration with track changes; journal .docx submission
✓
✓
Reveal.js (`revealjs`)
Interactive HTML presentations with code output
—
✓
Beamer (`beamer`)
PDF presentations; conference talks with LaTeX typesetting
✓
✓
PowerPoint (`pptx`)
PowerPoint-compatible presentations for non-R users
✓
✓
ioslides / Slidy
Simple HTML presentations (R Markdown only)
✓
—
Quarto-Specific Features
Section Overview
What you will learn: Quarto’s built-in callout blocks; multi-column and panel layouts; tabsets; the freeze execution option; and the _quarto.yml project configuration file
Callout Blocks
Callout blocks draw attention to notes, tips, warnings, and important information. They are a Quarto native feature — no extra packages or CSS required.
::: {.callout-note}## Note titleThis is a note callout — used for supplementary information.:::::: {.callout-tip}## Tip titleThis is a tip callout — used for best practices and shortcuts.:::::: {.callout-warning}## Warning titleThis is a warning callout — used for common mistakes and pitfalls.:::::: {.callout-important}## Important titleThis is an important callout — used for critical information.:::::: {.callout-caution}## Caution titleThis is a caution callout — used for potential issues requiring care.:::
Rendered:
Note title
This is a note callout — used for supplementary information.
Tip title
This is a tip callout — used for best practices and shortcuts.
Warning title
This is a warning callout — used for common mistakes and pitfalls.
Important title
This is an important callout — used for critical information.
Caution title
This is a caution callout — used for potential issues requiring care.
Callouts can be collapsed by default:
::: {.callout-note collapse="true"}## Expandable noteThis content is hidden until the reader clicks the heading.:::
Expandable note
This content is hidden until the reader clicks the heading.
Callouts without a title:
::: {.callout-tip appearance="simple"}A quick tip with no header.:::
A quick tip with no header.
Multi-Column Layouts
Two-Column Body Text
:::: {.columns}::: {.column width="60%"}**Main analysis**The vowel chart reveals that the learner's /iː/ is more centralisedthan the RP target, with F2 approximately 200 Hz lower than expected.:::::: {.column width="40%"}**Key finding**- /iː/ centralised- /ɔː/ raised- /æ/ raised and backed:::::::
Main analysis
The vowel chart reveals that the learner’s /iː/ is more centralised than the RP target, with F2 approximately 200 Hz lower than expected.
Key finding
/iː/ centralised
/ɔː/ raised
/æ/ raised and backed
Figure Layouts
Place two figures side by side with independent captions and cross-reference labels:
::: {#fig-comparison layout-ncol=2}{#fig-raw}{#fig-lob}Vowel space before (left) and after (right) Lobanov normalisation.:::See @fig-comparison for the comparison, or specifically @fig-raw for raw Hz values.
Layout options: layout-ncol, layout-nrow, or a custom layout matrix:
Tabsets allow multiple versions of content in the same space — useful for showing results under different conditions, or code in multiple languages:
::: {.panel-tabset}## Raw HzContent for the raw Hz tab.## LobanovContent for the Lobanov normalisation tab.## NeareyContent for the Nearey normalisation tab.:::
Rendering a Quarto document re-executes all code chunks. For documents with long-running computations (large models, web scraping), this is expensive. The freeze option caches executed output so that chunks are only re-run when their code changes.
In _quarto.yml (applies to all documents in the project):
execute:freeze: auto # re-execute only when source code changes
In an individual document’s YAML:
execute:freeze:true # never re-execute — always use cached output
Cached output is stored in the _freeze/ directory. Commit this directory to version control so collaborators can render the document without re-running expensive computations.
The _quarto.yml Project File
A _quarto.yml file in the root of a project configures all documents simultaneously. This is the key advantage of the Quarto project system over R Markdown.
Any format: settings in _quarto.yml apply to all documents and can be overridden in individual documents:
format:html:theme: cosmotoc:truecode-fold: showfig-height:5fig-width:7execute:echo:truemessage:falsewarning:falsecache:falsefreeze: auto
Cross-References
Section Overview
What you will learn: How to label and reference figures, tables, sections, and equations in both R Markdown (via bookdown) and Quarto (natively)
In Quarto
Quarto has built-in cross-references. Every referenceable element needs a label with the appropriate prefix.
Figures
Label a figure chunk with #| label: fig-something and reference it with @fig-something:
` ``{r}#| label: fig-vowel-chart#| fig-cap: "Vowel space of the L1-German learner vs. RP native speakers"#| fig-height: 6plot(vowel_chart)` ``The results are shown in @fig-vowel-chart.
For Markdown images:
{#fig-vowel-chart}As shown in @fig-vowel-chart, the learner's vowels are displaced.
Tables
` ``{r}#| label: tbl-freq#| tbl-cap: "Top 20 words by frequency"freq_table |> flextable()` ``@tbl-freq shows the 20 most frequent words.
Sections
## Results {#sec-results}See @sec-results for the full discussion.
Equations
$$F_{\text{Lobanov}} = \frac{F - \bar{F}}{SD_F}$$ {#eq-lobanov}As shown in @eq-lobanov, Lobanov normalisation is a z-score transformation.
Reference Formatting
Quarto formats cross-references automatically: @fig-vowel-chart becomes “Figure 1”, @tbl-freq becomes “Table 1”, @sec-results becomes “Section 3”, and @eq-lobanov becomes “Equation 1”. The prefix text can be customised in _quarto.yml:
See Figure \@ref(fig:vowel-chart) and Table \@ref(tab:freq-table).(ref:vowel-chart-cap) Vowel space of the L1-German learner vs. RP native speakers.` ``{r vowel-chart, fig.cap="(ref:vowel-chart-cap)"}plot(vowel_chart)` ``
Citations and Bibliographies
Section Overview
What you will learn: How to manage references with BibTeX; how to cite sources in Markdown; how to specify citation styles with CSL files; and how Quarto’s visual editor simplifies citation management
BibTeX Reference Files
Both R Markdown and Quarto use BibTeX (.bib) files for bibliographies. A .bib file contains entries like:
@book{johnson2003acoustic,author = {Johnson, Keith},title = {Acoustic and Auditory Phonetics},year = {2003},publisher = {Blackwell},address = {Oxford}}@article{lobanov1971classification,author = {Lobanov, B. M.},title = {Classification of Russian vowels spoken by different speakers},journal = {Journal of the Acoustical Society of America},year = {1971},volume = {49},number = {2},pages = {606--608}}@manual{schweinberger2026notebooks,author = {Schweinberger, Martin},title = {R Markdown and Quarto: Creating Reproducible Documents},note = {https://ladal.edu.au/tutorials/notebooks/notebooks.html},year = {2026},organization = {The Language Technology and Data Analysis Laboratory (LADAL)},address = {Brisbane},edition = {2026.03.10}}
Point your document at the .bib file:
bibliography: references.bib
Citation Syntax
[@johnson2003acoustic] # (Johnson 2003)[@johnson2003acoustic, p. 45] # (Johnson 2003, p. 45)[@johnson2003acoustic; @lobanov1971] # (Johnson 2003; Lobanov 1971)@johnson2003acoustic # Johnson (2003) — narrative citation[-@johnson2003acoustic] # (2003) — suppress author name
Rendered examples:
Parenthetical: formants are described in detail in (Johnson 2003)
Narrative: Johnson (2003) provides a thorough introduction to formant analysis
The default citation style is Chicago author-date. To use a different style, download a CSL file from the Zotero Style Repository and point your document at it:
Pandoc automatically inserts the formatted reference list at the end of the document. In Quarto, add a # References {-} heading at the bottom; in R Markdown, the list appears after the last section or after # References.
To place the reference list somewhere other than the end of the document, use a div:
::: {#refs}:::
Quarto Visual Editor and Zotero Integration
Quarto’s Visual Editor (switch via the Source/Visual toggle in RStudio) provides a GUI for inserting citations. It integrates with:
Zotero (via the Zotero connector) — search your Zotero library and insert citations by clicking
DOI lookup — paste a DOI and Quarto fetches the bibliographic data automatically
CrossRef search — search published literature by title or author
The visual editor automatically adds new entries to your .bib file and inserts the citation key in the document.
Parameterised Reports
Section Overview
What you will learn: How to use YAML parameters to create one document template that generates multiple outputs — for example, one report per speaker, corpus, or time period
Defining Parameters
Parameters are defined in the YAML header and accessed in R code via params$name:
R Markdown:
title:"Vowel Chart Report: MY_SPEAKER" # use params$speaker here in practiceparams:speaker:"ms"variety:"RP"max_formant:5500
In both cases, access the parameters in code chunks with params$speaker, params$variety, etc.
Using Parameters in Code
Code
# Filter data to the speaker specified in paramsspeaker_data <- voweldata |> dplyr::filter(subject == params$speaker)# Use the variety name in a plot titleggplot(speaker_data, aes(x = F2, y = F1)) +geom_text(aes(label = ipa)) +labs(title =paste("Vowel space —", params$variety, "variety"))
Rendering Multiple Reports
To generate one report per speaker programmatically:
What you will learn: Concrete practices for making your R Markdown and Quarto documents maximally reproducible — for yourself, your collaborators, and your readers
Always Include sessionInfo()
R package versions change. A script that works with ggplot2 3.4.0 may behave differently with 3.5.0. Always include sessionInfo() at the end of your document so readers can see exactly which package versions were used:
Code
sessionInfo()
Set a Random Seed
Any analysis involving random numbers (simulation, bootstrapping, random train/test splits, k-means clustering) must set a seed for reproducibility:
Code
set.seed(2026)
Place set.seed() at the top of your setup chunk or immediately before the relevant analysis.
Use here::here() for File Paths
Absolute file paths (e.g. C:/Users/martin/Documents/project/data.csv) break when the project is moved or shared. Use here::here() to construct paths relative to the project root:
The renv package creates a project-specific library with pinned package versions, so the project can be restored exactly on any machine:
Code
# Initialise renv in your projectrenv::init()# After installing/updating packages, snapshot the libraryrenv::snapshot()# Collaborator restores exact package versionsrenv::restore()
Avoid Absolute Dates
Use date: last-modified (Quarto) or date: "YYYY-MM-DD" set via Sys.Date() as an inline R expression (R Markdown) rather than a hardcoded date string — the document date always reflects when it was last rendered.
Use Version Control
Store your .Rmd/.qmd, .bib, data files, and renv.lock in a Git repository. This makes every change traceable and enables collaboration via GitHub or GitLab.
Practice
Why
Include `sessionInfo()`
Records exact package versions used
Set `set.seed()`
Ensures random results are reproducible
Use `here::here()` paths
File paths work on any machine
Use `renv` for package management
Pins package versions for exact reproducibility
Use version control (Git)
Tracks changes; enables collaboration
Use `freeze: auto` in Quarto
Avoids re-running unchanged code on project rebuild
Cache expensive chunks with `cache: true`
Speeds up rendering for expensive computations
Use `embed-resources: true` for HTML
Self-contained file — no broken relative links
Write `echo: true` for analytical chunks
Readers can verify and reproduce the analysis
Document all data sources
Provenance of data is clear and traceable
Common Problems and Solutions
Section Overview
What you will learn: The most common errors encountered when rendering R Markdown and Quarto documents, and how to fix them
Problem
Cause
Solution
Document fails to render with a LaTeX error
Missing LaTeX package or TinyTeX not installed
Run `tinytex::install_tinytex()` or `tinytex::tlmgr_install('pkg')`
Unicode/IPA symbols appear as boxes or ? in PDF
`pdflatex` engine does not support Unicode
Set `latex_engine: xelatex` (R Markdown) or `latex-engine: xelatex` (Quarto)
Figures not showing in PDF
File path is wrong or figure is not generated
Check path with `file.exists()`; use `here::here()`
`object 'x' not found` error
Chunk that creates the object ran after the chunk that uses it
Reorder chunks so objects are created before they are used
Package not found error during render
Package installed in global library but not in `renv` library
Run `renv::restore()` or `renv::install('pkg')`
YAML parsing error
Incorrect indentation or special characters in YAML values
Wrap values containing colons or special chars in quotes; use spaces not tabs
Cross-reference not resolving (`@fig-X` shows literally)
Chunk label missing the `fig-` prefix or wrong syntax
Ensure label starts with `fig-` and `#|` syntax is used
Cache not updating after data change
Cache key is based on code only — data changes are not detected
Add `dependson` option pointing to the data-loading chunk
HTML output has broken images
Path is absolute or relative to wrong directory
Use `here::here()` or set `embed-resources: true` in Quarto
Chunk option has no effect
Option spelled incorrectly or wrong syntax (`.` vs `-`)
Check spelling: R Markdown uses `.` (e.g. `fig.height`); Quarto uses `-` (e.g. `fig-height`)
Citation and Session Info
Schweinberger, Martin. 2026. R Markdown and Quarto: Creating Reproducible Documents. Brisbane: The Language Technology and Data Analysis Laboratory (LADAL). url: https://ladal.edu.au/tutorials/notebooks/notebooks.html (Version 2026.03.10).
@manual{schweinberger2026notebooks,
author = {Schweinberger, Martin},
title = {R Markdown and Quarto: Creating Reproducible Documents},
note = {https://ladal.edu.au/tutorials/notebooks/notebooks.html},
year = {2026},
organization = {The Language Technology and Data Analysis Laboratory (LADAL)},
address = {Brisbane},
edition = {2026.03.10}
}
This tutorial was written with the assistance of Claude (claude.ai), a large language model created by Anthropic. Claude was used to substantially expand and restructure a shorter existing LADAL tutorial on R Notebooks and Markdown. All content was reviewed and approved by Martin Schweinberger, who takes full responsibility for its accuracy.
For a thorough introduction to formant analysis see Johnson (2003).↩︎
Source Code
---title: "R Markdown and Quarto: Creating Reproducible Documents"author: "Martin Schweinberger"format: html: toc: true toc-depth: 4 code-fold: show code-tools: true theme: cosmo---```{r setup, echo=FALSE, message=FALSE, warning=FALSE}options(stringsAsFactors = FALSE)options("scipen" = 100, "digits" = 4)```{ width=100% }# Introduction {#intro}This tutorial introduces R Markdown and Quarto as tools for combining code, output, and narrative text in a single, dynamic, and fully reproducible document. Whether you are writing a corpus analysis report, a phonetics study, or a data science notebook, these tools allow you to weave together your R code, its output, and your prose explanation into a polished, shareable document.{ width=15% style="float:right; padding:10px" }The tutorial is aimed at beginners and intermediate R users in the humanities and social sciences. It covers the full workflow: understanding what R Markdown and Quarto are and how they differ, learning Markdown syntax, configuring YAML headers, controlling code chunk behaviour, producing multiple output formats, and using Quarto's advanced features such as callout blocks, cross-references, citations, and project-level configuration.By the end of this tutorial you will be able to:- Create a reproducible R Markdown or Quarto document from scratch- Write well-structured Markdown prose with headings, lists, tables, and figures- Control how code chunks are displayed and executed- Export your work as HTML, PDF, Word, or a presentation- Use Quarto-specific features: callouts, cross-references, freeze, and `_quarto.yml`- Manage citations and bibliographies with BibTeX::: {.callout-note}## Prerequisite KnowledgeBefore working through this tutorial, you should be familiar with:- Basic R syntax and RStudio ([Getting Started with R](/tutorials/intror/intror.html))- Saving and loading files in R ([Loading, Saving, and Generating Data in R](/tutorials/load/load.html)):::::: {.callout-note}## CitationSchweinberger, Martin. 2026. *R Markdown and Quarto: Creating Reproducible Documents*. Brisbane: The Language Technology and Data Analysis Laboratory (LADAL). url: https://ladal.edu.au/tutorials/notebooks/notebooks.html (Version 2026.03.10).:::---# Setup {#setup}## Installing Packages {-}```{r install, eval=FALSE, message=FALSE, warning=FALSE}# Run once — comment out after installationinstall.packages("rmarkdown")install.packages("knitr")install.packages("tidyverse")install.packages("flextable")install.packages("kableExtra")install.packages("bookdown") # for cross-references in R Markdown# Quarto is installed separately from https://quarto.org/docs/get-started/```## Loading Packages {-}```{r load_packages, message=FALSE, warning=FALSE}library(rmarkdown)library(knitr)library(tidyverse)library(flextable)klippy::klippy()```---# What Are R Markdown and Quarto? {#what}::: {.callout-note}## Section Overview**What you will learn:** What R Markdown and Quarto are; why reproducible documents matter; and how these tools fit into a modern research workflow:::## The Problem They Solve {-}A typical research workflow involves several disconnected steps: running R code in a script, copying results into a Word document, inserting figures manually, and then updating everything again when the data changes. This workflow is fragile — a change in the data means re-running the code, re-copying the numbers, and re-inserting the figures, with every step introducing the risk of inconsistency.**R Markdown** and **Quarto** solve this by integrating code, output, and prose in a single source document. When you render the document, the code runs, the output is inserted automatically, and the prose and results are always in sync. The document is **reproducible**: anyone with the source file and data can re-render it and obtain exactly the same output.## R Markdown {-}R Markdown was introduced by the `knitr` package [@xie2015knitr] and formalised in the `rmarkdown` package [@allaire2023rmarkdown]. An R Markdown document (`.Rmd`) combines:- A **YAML header** specifying document metadata and output format- **Markdown prose** for narrative text- **R code chunks** that are executed when the document is renderedR Markdown documents are rendered by `knitr` (which executes the R code and weaves the output into the document) followed by Pandoc (which converts the resulting Markdown into the target output format — HTML, PDF, Word, etc.).## Quarto {-}Quarto is the next-generation publishing system developed by Posit (formerly RStudio). A Quarto document (`.qmd`) uses the same Markdown + code chunk approach as R Markdown, but with several important advances:- **Language-agnostic:** supports R, Python, Julia, and Observable JS in the same document- **Unified syntax:** chunk options use `#|` comments rather than chunk header parameters- **Richer output features:** built-in callout blocks, cross-references, layouts, and theming- **Project system:** `_quarto.yml` configures entire websites, books, or presentations- **Better defaults:** produces cleaner HTML and PDF output out of the boxFor new projects, Quarto is recommended. R Markdown remains fully supported and is still widely used. This tutorial covers both.---# R Markdown vs. Quarto {#comparison}::: {.callout-note}## Section Overview**What you will learn:** How R Markdown and Quarto differ in syntax, features, and workflow; and when to use each:::```{r comparison_table, echo=FALSE, message=FALSE, warning=FALSE}data.frame( Feature = c( "File extension", "Engine", "Language support", "Chunk options syntax", "YAML location", "Callout blocks", "Cross-references", "Project system", "Slides", "Books / websites", "Inline code", "Freeze / caching", "Maintained by", "When to use" ), `R Markdown` = c( "`.Rmd`", "`knitr` → Pandoc", "Primarily R; Python via `reticulate`", "Inside chunk header: `{r label, echo=FALSE}`", "Document YAML header only", "Via `rmdformats` or custom CSS", "Via `bookdown` package", "Limited — manual setup", "`ioslides`, `Slidy`, `Beamer` (PDF)", "`bookdown`, `blogdown`, `distill`", "`` `r expr` ``", "Via `knitr` cache", "Posit / community", "Existing `.Rmd` projects; R-only workflows" ), Quarto = c( "`.qmd`", "`knitr` or `jupyter` → Pandoc", "R, Python, Julia, Observable JS", "`#|` comments inside chunk: `#| echo: false`", "Document YAML + `_quarto.yml` project file", "Built-in (`.callout-note`, `.callout-warning`, etc.)", "Built-in `@fig-`, `@tbl-`, `@sec-` syntax", "`_quarto.yml` for websites, books, presentations", "Reveal.js (HTML); Beamer (PDF); PowerPoint", "Built-in `quarto render` project commands", "`` `{r} expr` `` or `` `r expr` ``", "`freeze: auto` in `_quarto.yml`", "Posit", "New projects; multi-language; websites; books" ), check.names = FALSE) |> flextable() |> flextable::set_table_properties(width = 1, layout = "autofit") |> flextable::theme_zebra() |> flextable::fontsize(size = 10) |> flextable::set_caption("R Markdown vs. Quarto: feature comparison")```::: {.callout-tip}## Which Should I Use?- **Use R Markdown** if you are working on an existing `.Rmd` project, or if you need a package that is R Markdown-specific (e.g. `blogdown`, `bookdown`)- **Use Quarto** for all new projects — it is more powerful, better maintained, and handles multi-language workflows elegantly- **Both** render to the same output formats via Pandoc, so skills transfer directly between them:::---# Creating Your First Document {#first}::: {.callout-note}## Section Overview**What you will learn:** How to create a new R Markdown or Quarto document in RStudio; what the basic structure looks like; and how to render it:::## In RStudio {-}**R Markdown:** Go to **File → New File → R Markdown**. Choose the output format (HTML is the default) and click **OK**. RStudio creates a template `.Rmd` file with a YAML header, some sample text, and a few code chunks.**Quarto:** Go to **File → New File → Quarto Document**. Again choose your output format and click **Create**. RStudio creates a template `.qmd` file.## Basic Structure {-}Both document types share the same three-part structure:```markdown---YAML header---Markdown prose` ``{r}# R code chunk` `````## Rendering {-}**R Markdown:** Click the **Knit** button in RStudio (or run `rmarkdown::render("file.Rmd")` in the console).**Quarto:** Click the **Render** button in RStudio (or run `quarto render file.qmd` in the terminal).Both processes: execute all code chunks → weave output into the document → convert to the target format via Pandoc.::: {.callout-tip}## Keyboard Shortcut`Ctrl+Shift+K` (Windows/Linux) or `Cmd+Shift+K` (Mac) renders the current document in RStudio — for both R Markdown and Quarto.:::---# YAML Headers {#yaml}::: {.callout-note}## Section Overview**What you will learn:** What YAML is; the most important YAML fields for R Markdown and Quarto; how to configure output formats, themes, and table of contents; and how Quarto's YAML extends R Markdown's:::## What Is YAML? {-}YAML (Yet Another Markup Language) is a human-readable data serialisation format used to store configuration. In R Markdown and Quarto, the YAML header sits between two sets of `---` at the top of the document and controls metadata (title, author, date) and rendering options (output format, theme, table of contents).YAML is indentation-sensitive — use spaces, not tabs, and be consistent with nesting.## R Markdown YAML {-}A minimal R Markdown YAML header:```yamltitle:"My Analysis"author:"Martin Schweinberger"date:"2026-03-10"output: html_document```A fully configured HTML output header:```yamltitle:"Corpus Frequency Analysis"author:"Martin Schweinberger"date:"YYYY-MM-DD # use Sys.Date() in practice"output:html_document:toc:truetoc_depth:3toc_float:truenumber_sections:truetheme: cosmohighlight: tangocode_folding: showdf_print: pagedbibliography: references.bibcsl: unified-style-linguistics.csl```Multiple output formats in one document:```yamltitle:"My Document"output:html_document:toc:truepdf_document:toc:trueword_document:reference_docx: template.docx``````{r rmd_yaml_table, echo=FALSE, message=FALSE, warning=FALSE}data.frame( Field = c( "`title`", "`author`", "`date`", "`output`", "`toc`", "`toc_depth`", "`toc_float`", "`number_sections`", "`theme`", "`highlight`", "`code_folding`", "`df_print`", "`bibliography`", "`csl`", "`params`" ), Description = c( "Document title — appears as the main heading", "Author name(s) — can be a list", "Date string or inline R expression e.g. `` `r Sys.Date()` ``", "Output format: `html_document`, `pdf_document`, `word_document`, etc.", "Include table of contents (`true`/`false`)", "Depth of headings included in the ToC (default 3)", "Float the ToC in the sidebar (HTML only)", "Auto-number sections (`true`/`false`)", "Bootstrap theme for HTML (cosmo, flatly, journal, etc.)", "Syntax highlighting style (tango, pygments, kate, etc.)", "Show/hide code (`show`, `hide`, `none`)", "How data frames are printed (`default`, `kable`, `tibble`, `paged`)", "Path to `.bib` bibliography file", "Citation style language file for reference formatting", "Parameterised report inputs — see Parameterised Reports section" ), check.names = FALSE) |> flextable() |> flextable::set_table_properties(width = 1, layout = "autofit") |> flextable::theme_zebra() |> flextable::fontsize(size = 10) |> flextable::set_caption("Common R Markdown YAML fields")```## Quarto YAML {-}Quarto's YAML uses nested `format:` keys rather than `output:`, and adds many new fields:```yamltitle:"Corpus Frequency Analysis"author:-name:"Martin Schweinberger"affiliation:"The University of Queensland"email:"m.schweinberger@uq.edu.au"date: last-modifieddate-format:"DD MMMM YYYY"format:html:toc:truetoc-depth:4toc-title:"Contents"toc-location: leftnumber-sections:truenumber-depth:3code-fold: showcode-tools:truecode-line-numbers:truetheme: cosmohighlight-style: tangoembed-resources:truesmooth-scroll:truecitations-hover:truefootnotes-hover:truepdf:documentclass: articlegeometry: margin=2.5cmtoc:truedocx:reference-doc: template.docxexecute:echo:truewarning:falsemessage:falsecache:falsebibliography: references.bibcsl: unified-style-linguistics.csllang: en-GB``````{r quarto_yaml_table, echo=FALSE, message=FALSE, warning=FALSE}data.frame( Field = c( "`title`", "`author`", "`date: last-modified`", "`date-format`", "`format: html:`", "`toc-location`", "`code-fold`", "`code-tools`", "`code-line-numbers`", "`embed-resources`", "`smooth-scroll`", "`citations-hover`", "`execute:`", "`execute: cache`", "`lang`", "`bibliography`", "`csl`" ), Description = c( "Document title", "Can be a list with `name`, `affiliation`, `email`, `orcid`", "Automatically set to the file's last-modified date", "Date display format using `dayjs` tokens", "HTML output options — nested under `format: html:`", "Position of ToC: `left`, `right`, `body`", "Code folding: `show`, `hide`, `true`, `false`", "Show a toolbar to copy code or view source", "Add line numbers to code blocks", "Bundle all dependencies into a single self-contained HTML file", "Enable smooth scrolling between sections", "Show citation details on hover", "Global chunk execution defaults — applies to all chunks", "Cache all chunk outputs to speed up re-rendering", "Document language for hyphenation and accessibility", "Path to `.bib` file", "Citation style language file" ), check.names = FALSE) |> flextable() |> flextable::set_table_properties(width = 1, layout = "autofit") |> flextable::theme_zebra() |> flextable::fontsize(size = 10) |> flextable::set_caption("Common Quarto YAML fields")```---# Code Chunks {#chunks}::: {.callout-note}## Section Overview**What you will learn:** How to insert and label code chunks; how to control their execution, display, and output with chunk options; and how R Markdown and Quarto chunk syntax differ:::## Inserting a Code Chunk {-}**Keyboard shortcut:** `Ctrl+Alt+I` (Windows/Linux) or `Cmd+Option+I` (Mac) inserts a new code chunk in RStudio.**R Markdown syntax** — options go in the chunk header:```markdown` ` `{r my-chunk-label, echo=TRUE, message=FALSE, warning=FALSE}# R code here` ` ````**Quarto syntax** — options go inside the chunk as `#|` comments:```markdown` ` `{r}#| label: my-chunk-label#| echo: true#| message: false#| warning: false# R code here` ` ````Both syntaxes are valid in Quarto, but the `#|` style is preferred because it is language-agnostic (the same syntax works for Python, Julia, etc.) and keeps chunk options inside the chunk where they are easier to see.## Chunk Option Reference {-}```{r chunk_options_table, echo=FALSE, message=FALSE, warning=FALSE}data.frame( Option = c( "`label`", "`echo`", "`eval`", "`include`", "`message`", "`warning`", "`error`", "`results`", "`output`", "`fig.height` / `fig-height`", "`fig.width` / `fig-width`", "`fig.cap` / `fig-cap`", "`fig.align` / `fig-align`", "`fig.show` / `fig-show`", "`out.width` / `out-width`", "`cache`", "`dependson`", "`child`", "`code`", "`collapse`" ), `R Markdown` = c( "`label`", "`echo`", "`eval`", "`include`", "`message`", "`warning`", "`error`", "`results`", "—", "`fig.height`", "`fig.width`", "`fig.cap`", "`fig.align`", "`fig.show`", "`out.width`", "`cache`", "`dependson`", "`child`", "`code`", "`collapse`" ), Quarto = c( "`label`", "`echo`", "`eval`", "`include`", "`message`", "`warning`", "`error`", "`results`", "`output`", "`fig-height`", "`fig-width`", "`fig-cap`", "`fig-align`", "`fig-show`", "`out-width`", "`cache`", "`dependson`", "`child`", "`code`", "`collapse`" ), Effect = c( "Unique chunk identifier (required for cross-refs and caching)", "`true` show code; `false` hide code; `fenced` show with delimiters", "`true` run the chunk; `false` skip execution entirely", "`false` run but suppress ALL output including code, results, messages", "`false` suppress package messages (e.g. `library()` output)", "`false` suppress warnings", "`true` show errors instead of stopping render", "`hide` suppress printed output; `asis` pass raw HTML/Markdown through", "Quarto alias for `results`", "Plot height in inches (default 5)", "Plot width in inches (default 7)", "Figure caption string", "`left`, `center`, `right`", "`hold` collect all plots; `hide` suppress plots", "Scale output width e.g. `'80%'` or `'400px'`", "`true` cache chunk output to disk", "Labels of chunks this chunk depends on for cache invalidation", "Path to a child `.Rmd`/`.qmd` to include", "Override code displayed in the chunk", "`true` collapse code and output into one block" ), check.names = FALSE) |> flextable() |> flextable::set_table_properties(width = 1, layout = "autofit") |> flextable::theme_zebra() |> flextable::fontsize(size = 9.5) |> flextable::set_caption("Code chunk options: R Markdown vs. Quarto syntax and effects")```## Practical Examples {-}Show code but hide output:```markdown` ``{r}#| echo: true#| output: falsesummary(mtcars)` `````Hide code, show only the plot:```markdown` ``{r}#| echo: false#| fig-height: 5#| fig-width: 7#| fig-cap: "Distribution of word lengths"#| fig-align: centerhist(nchar(words))` `````Run chunk but suppress everything (useful for setup):```markdown` ``{r}#| include: falselibrary(tidyverse)library(flextable)` `````Display a figure at 80% page width, centred:```markdown` ``{r}#| out-width: "80%"#| fig-align: center#| fig-cap: "Vowel space of RP speakers"plot(vowel_chart)` `````Cache an expensive computation:```markdown` ``{r}#| label: heavy-model#| cache: truemodel <- lmer(RT ~ Frequency + (1|Subject), data = lexdec)` `````## Global Chunk Options {-}Setting options individually on every chunk is tedious. Use a setup chunk to set defaults for the whole document.**R Markdown:**```markdown` ``{r setup, include=FALSE}knitr::opts_chunk$set( echo = TRUE, message = FALSE, warning = FALSE, fig.height = 5, fig.width = 7, fig.align = "center")` `````**Quarto** — set in the YAML `execute:` block instead:```yamlexecute:echo:truemessage:falsewarning:false```Figure defaults in Quarto go under `fig-`:```yamlformat:html:fig-height:5fig-width:7fig-align: center```## Inline Code {-}Inline code embeds a computed value directly in prose without a separate code chunk:**R Markdown:** write a backtick followed immediately by `r`, then a space, your expression, and a closing backtick — directly in prose. When rendered, the expression is replaced by its computed value — e.g. *The corpus contains 4,572 tokens.***Quarto:** the equivalent syntax is a backtick followed by `{r}`, a space, your expression, and a closing backtick — placed in prose. The older R Markdown syntax also works in Quarto.Inline code is rendered inline — the expression is replaced with its value in the output. This ensures numbers in your prose always match your data.---# Markdown Syntax Reference {#markdown}::: {.callout-note}## Section Overview**What you will learn:** The full Markdown syntax supported by R Markdown and Quarto, from basic formatting to advanced features like footnotes, math, diagrams, and HTML:::## Headings {-}**Command:**```markdown# Heading 1## Heading 2### Heading 3#### Heading 4##### Heading 5###### Heading 6```**Rendered:**# Heading 1## Heading 2### Heading 3#### Heading 4##### Heading 5###### Heading 6Headings can carry a custom ID for cross-referencing and linking:```markdown## Results {#sec-results}```And can carry Quarto classes to suppress numbering:```markdown## Appendix {.unnumbered}```## Emphasis {-}**Command:**```markdown*italic* _italic_**bold** __bold__***bold and italic***~~strikethrough~~```**Rendered:***italic* / _italic_ · **bold** / __bold__ · ***bold and italic*** · ~~strikethrough~~Quarto also supports:```markdownH~2~O (subscript)E = mc^2^ (superscript)[mark]{.mark} (highlight — requires appropriate CSS)```**Rendered:** H~2~O · E = mc^2^ · [mark]{.mark}## Lists {-}### Unordered List {-}```markdown- Item 1- Item 2 - Subitem 2.1 - Subitem 2.2- Item 3```- Item 1- Item 2 - Subitem 2.1 - Subitem 2.2- Item 3### Ordered List {-}```markdown1. First item2. Second item3. Third item 1. Subitem 3.1 2. Subitem 3.2```1. First item2. Second item3. Third item 1. Subitem 3.1 2. Subitem 3.2### Task Lists {-}```markdown- [x] Completed task- [ ] Incomplete task- [ ] Another task - [x] Completed subtask - [ ] Pending subtask```- [x] Completed task- [ ] Incomplete task- [ ] Another task - [x] Completed subtask - [ ] Pending subtask### Definition Lists {-}```markdownMonophthong: A vowel with a single, stable tongue position during production.Diphthong: A vowel that involves a glide from one tongue position to another.Formant: A resonant frequency band produced by the vocal tract shape.```Monophthong: A vowel with a single, stable tongue position during production.Diphthong: A vowel that involves a glide from one tongue position to another.Formant: A resonant frequency band produced by the vocal tract shape.## Links {-}```markdown[LADAL](https://ladal.edu.au) # external link[Introduction](#intro) # internal anchor link[Schweinberger 2026](references.html#ref-sch26) # link to reference<m.schweinberger@uq.edu.au> # auto-linked email```**Rendered:** [LADAL](https://ladal.edu.au) · [Introduction](#intro) · <m.schweinberger@uq.edu.au>## Images {-}Basic image:```markdown```Image with width and alignment (Quarto/Pandoc attribute syntax):```markdown{width=60% fig-align="center"}```Floating image (HTML inline style):```markdown{ width=15% style="float:right; padding:10px" }```Image with a cross-referenceable label:```markdown{#fig-vc width=70%}See @fig-vc for the vowel chart.```Two images side by side using Quarto layout:```markdown::: {layout-ncol=2}{#fig-left}{#fig-right}:::```## Blockquotes {-}```markdown> This is a blockquote.>> Spanning multiple paragraphs.>> > This is a nested blockquote.```> This is a blockquote.>> Spanning multiple paragraphs.>> > This is a nested blockquote.Blockquotes with attribution:```markdown> The limits of my language mean the limits of my world.>> — Ludwig Wittgenstein, *Tractatus Logico-Philosophicus* (1921)```> The limits of my language mean the limits of my world.>> — Ludwig Wittgenstein, *Tractatus Logico-Philosophicus* (1921)## Code {-}### Inline Code {-}```markdownUse `read.table()` to load tab-delimited files.```Use `read.table()` to load tab-delimited files.### Code Blocks {-}Fenced code blocks with language tags produce syntax highlighting:````markdown```rcorpus <-readLines("corpus.txt")tokens <-unlist(strsplit(corpus, "\\s+"))``````````rcorpus <-readLines("corpus.txt")tokens <-unlist(strsplit(corpus, "\\s+"))```Supported language tags include: `r`, `python`, `bash`, `markdown`, `yaml`, `json`, `html`, `latex`, `praat`, and many more.## Tables {-}### Basic Markdown Table {-}```markdown| Vowel | IPA | F1 (Hz) | F2 (Hz) ||-------|-----|---------|---------|| heed | iː | 276 | 2338 || hid | ɪ | 393 | 2174 || head | e | 600 | 1926 || had | æ | 916 | 1473 |```| Vowel | IPA | F1 (Hz) | F2 (Hz) ||-------|-----|---------|---------|| heed | iː | 276 | 2338 || hid | ɪ | 393 | 2174 || head | e | 600 | 1926 || had | æ | 916 | 1473 |### Column Alignment {-}```markdown| Left | Centre | Right ||:---------|:--------:|---------:|| text | text | 1,234 || text | text | 5,678 |```| Left | Centre | Right ||:---------|:--------:|---------:|| text | text | 1,234 || text | text | 5,678 |For production tables — sortable columns, striped rows, captions, cross-references — use `flextable()` or `knitr::kable()` in a code chunk rather than raw Markdown tables.## Footnotes {-}```markdownFormants are resonant frequencies of the vocal tract.[^1][^1]: For a thorough introduction to formant analysis see Johnson (2003).```Formants are resonant frequencies of the vocal tract.[^fn1][^fn1]: For a thorough introduction to formant analysis see Johnson (2003).Inline footnotes (Quarto/Pandoc):```markdownFormants are resonant frequencies of the vocal tract.^[For a thorough introduction see Johnson (2003).]```## Math Expressions {-}Inline LaTeX math:```markdownThe polarity ratio is $P = \frac{n_+}{n_-}$.```The polarity ratio is $P = \frac{n_+}{n_-}$.Display (block) math:```markdown$$F_{\text{Lobanov}} = \frac{F - \bar{F}_{\text{speaker}}}{SD_{F,\text{speaker}}}$$```$$F_{\text{Lobanov}} = \frac{F - \bar{F}_{\text{speaker}}}{SD_{F,\text{speaker}}}$$## Mermaid Diagrams {-}Quarto supports Mermaid diagrams natively with no extra packages:````markdown```{mermaid}graph TD A[Raw audio] --> B[Praat formant extraction] B --> C[Tab-delimited .txt file] C --> D[Load in R] D --> E[Normalisation] E --> F[Vowel chart]``````````{mermaid}graph TD A[Raw audio] --> B[Praat formant extraction] B --> C[Tab-delimited .txt file] C --> D[Load in R] D --> E[Normalisation] E --> F[Vowel chart]```Other diagram types: `flowchart`, `sequenceDiagram`, `gantt`, `classDiagram`, `stateDiagram`, `erDiagram`, `pie`.## HTML Elements {-}Raw HTML passes through directly in both R Markdown and Quarto HTML output.Expandable section:```markdown<details> <summary>Click to expand: full model output</summary> Content hidden until expanded. Useful for supplementary material.</details>```<details> <summary>Click to expand: full model output</summary> Content hidden until expanded. Useful for supplementary material.</details>Coloured span (requires inline CSS):```markdown<span style="color: #E67E22; font-weight: bold;">Important term</span>```<span style="color: #E67E22; font-weight: bold;">Important term</span>Keyboard key styling:```markdownPress <kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>K</kbd> to render.```Press <kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>K</kbd> to render.## Escaping Special Characters {-}Backslash escapes Markdown special characters:```markdown\*not italic\*\`not code\`\# not a heading \[not a link\]```\*not italic\* · \`not code\` · \# not a heading · \[not a link\]## Horizontal Rules {-}```markdown---***___```All three produce a horizontal rule:---## Emojis {-}```markdown:smile: :+1: :sparkles: :books: :bar_chart:```:smile: :+1: :sparkles: :books: :bar_chart:(Requires `emoji` extension or appropriate Pandoc version — works in Quarto HTML by default.)---# Output Formats {#formats}::: {.callout-note}## Section Overview**What you will learn:** How to render R Markdown and Quarto documents to HTML, PDF, Word, and presentation formats; what options are available for each; and how to choose the right format for your audience:::## HTML {-}HTML is the richest output format — it supports interactive widgets, floating tables of contents, collapsible code, hover citations, and smooth scrolling. It is the recommended format for sharing analysis online or via email.**R Markdown:**```yamloutput:html_document:toc:truetoc_float:truetheme: cosmocode_folding: showdf_print: paged```**Quarto:**```yamlformat:html:toc:truetoc-location: lefttheme: cosmocode-fold: showembed-resources:true # self-contained single file```::: {.callout-tip}## `embed-resources: true`By default, Quarto HTML output references external libraries (Bootstrap, highlight.js, etc.) via relative paths. Setting `embed-resources: true` bundles everything into a single `.html` file — ideal for sharing by email or uploading to a repository without worrying about broken relative paths.:::## PDF {-}PDF output requires a LaTeX distribution. The recommended option is TinyTeX, which can be installed from R:```{r tinytex, eval=FALSE}install.packages("tinytex")tinytex::install_tinytex()```**R Markdown:**```yamloutput:pdf_document:toc:truenumber_sections:truelatex_engine: xelatex # for Unicode and custom fontskeep_tex:true # keep the intermediate .tex file```**Quarto:**```yamlformat:pdf:documentclass: articlegeometry: margin=2.5cmtoc:truenumber-sections:truelatex-engine: xelatexinclude-in-header: preamble.tex # custom LaTeX preamble```::: {.callout-warning}## PDF and UnicodeIf your document contains IPA symbols, non-Latin scripts, or special characters, use `latex_engine: xelatex` (R Markdown) or `latex-engine: xelatex` (Quarto). The default `pdflatex` engine does not support Unicode. Also ensure your fonts support the required character ranges.:::## Word (.docx) {-}Word output is useful when collaborators need to add track-changes comments or when a journal requires `.docx` submission.**R Markdown:**```yamloutput:word_document:toc:truereference_docx: template.docx # custom styles template```**Quarto:**```yamlformat:docx:toc:truereference-doc: template.docxhighlight-style: github```To create a Word template: render a document to `.docx`, open it in Word, modify the Heading 1, Body Text, Code, and Caption styles to match your requirements, save it, and point `reference_docx`/`reference-doc` at it.## Presentations {-}### Quarto Reveal.js (HTML Slides) {-}Reveal.js is Quarto's primary presentation format — fully interactive, browser-based slides:```yamlformat:revealjs:theme: simple # default, simple, sky, moon, serif, solarizedslide-number:truechalkboard:true # interactive drawing on slidesincremental:true # bullet points appear one at a timefooter:"LADAL — ladal.edu.au"logo: /images/uq1.jpgtransition: slide # none, fade, slide, convex, concave, zoombackground-transition: fade```In a Reveal.js document, each `##` heading starts a new slide, and `---` creates a slide without a heading. Columns are created with:```markdown:::: {.columns}::: {.column width="50%"}Left column content:::::: {.column width="50%"}Right column content:::::::```### Beamer (PDF Slides) {-}```yamlformat:beamer:theme: Madridcolortheme: dolphinfonttheme: structureboldslide-level:2```### PowerPoint {-}```yamlformat:pptx:reference-doc: template.pptx```### R Markdown Presentations {-}```yamloutput:ioslides_presentation:widescreen:truesmaller:trueslidy_presentation:footer:"LADAL"beamer_presentation:theme: Madrid``````{r format_comparison, echo=FALSE, message=FALSE, warning=FALSE}data.frame( Format = c("HTML (`html_document`/`html`)", "PDF (`pdf_document`/`pdf`)", "Word (`word_document`/`docx`)", "Reveal.js (`revealjs`)", "Beamer (`beamer`)", "PowerPoint (`pptx`)", "ioslides / Slidy"), `Best for` = c( "Online sharing; interactive outputs; most feature-rich", "Print; journal submission; formal reports", "Collaboration with track changes; journal .docx submission", "Interactive HTML presentations with code output", "PDF presentations; conference talks with LaTeX typesetting", "PowerPoint-compatible presentations for non-R users", "Simple HTML presentations (R Markdown only)" ), `R Markdown` = c("✓","✓","✓","—","✓","✓","✓"), Quarto = c("✓","✓","✓","✓","✓","✓","—"), check.names = FALSE) |> flextable() |> flextable::set_table_properties(width = 1, layout = "autofit") |> flextable::theme_zebra() |> flextable::fontsize(size = 10) |> flextable::set_caption("Output format comparison: R Markdown vs. Quarto")```---# Quarto-Specific Features {#quarto}::: {.callout-note}## Section Overview**What you will learn:** Quarto's built-in callout blocks; multi-column and panel layouts; tabsets; the `freeze` execution option; and the `_quarto.yml` project configuration file:::## Callout Blocks {-}Callout blocks draw attention to notes, tips, warnings, and important information. They are a Quarto native feature — no extra packages or CSS required.```markdown::: {.callout-note}## Note titleThis is a note callout — used for supplementary information.:::::: {.callout-tip}## Tip titleThis is a tip callout — used for best practices and shortcuts.:::::: {.callout-warning}## Warning titleThis is a warning callout — used for common mistakes and pitfalls.:::::: {.callout-important}## Important titleThis is an important callout — used for critical information.:::::: {.callout-caution}## Caution titleThis is a caution callout — used for potential issues requiring care.:::```**Rendered:**::: {.callout-note}## Note titleThis is a note callout — used for supplementary information.:::::: {.callout-tip}## Tip titleThis is a tip callout — used for best practices and shortcuts.:::::: {.callout-warning}## Warning titleThis is a warning callout — used for common mistakes and pitfalls.:::::: {.callout-important}## Important titleThis is an important callout — used for critical information.:::::: {.callout-caution}## Caution titleThis is a caution callout — used for potential issues requiring care.:::Callouts can be collapsed by default:```markdown::: {.callout-note collapse="true"}## Expandable noteThis content is hidden until the reader clicks the heading.:::```::: {.callout-note collapse="true"}## Expandable noteThis content is hidden until the reader clicks the heading.:::Callouts without a title:```markdown::: {.callout-tip appearance="simple"}A quick tip with no header.:::```::: {.callout-tip appearance="simple"}A quick tip with no header.:::## Multi-Column Layouts {-}### Two-Column Body Text {-}```markdown:::: {.columns}::: {.column width="60%"}**Main analysis**The vowel chart reveals that the learner's /iː/ is more centralisedthan the RP target, with F2 approximately 200 Hz lower than expected.:::::: {.column width="40%"}**Key finding**- /iː/ centralised- /ɔː/ raised- /æ/ raised and backed:::::::```:::: {.columns}::: {.column width="60%"}**Main analysis**The vowel chart reveals that the learner's /iː/ is more centralised than the RP target, with F2 approximately 200 Hz lower than expected.:::::: {.column width="40%"}**Key finding**- /iː/ centralised- /ɔː/ raised- /æ/ raised and backed:::::::### Figure Layouts {-}Place two figures side by side with independent captions and cross-reference labels:```markdown::: {#fig-comparison layout-ncol=2}{#fig-raw}{#fig-lob}Vowel space before (left) and after (right) Lobanov normalisation.:::See @fig-comparison for the comparison, or specifically @fig-raw for raw Hz values.```Layout options: `layout-ncol`, `layout-nrow`, or a custom `layout` matrix:```markdown::: {layout="[[1,1],[1]]"}:::```## Tabsets {-}Tabsets allow multiple versions of content in the same space — useful for showing results under different conditions, or code in multiple languages:```markdown::: {.panel-tabset}## Raw HzContent for the raw Hz tab.## LobanovContent for the Lobanov normalisation tab.## NeareyContent for the Nearey normalisation tab.:::```::: {.panel-tabset}## Raw HzContent for the raw Hz tab.## LobanovContent for the Lobanov normalisation tab.## NeareyContent for the Nearey normalisation tab.:::## The `freeze` Option {-}Rendering a Quarto document re-executes all code chunks. For documents with long-running computations (large models, web scraping), this is expensive. The `freeze` option caches executed output so that chunks are only re-run when their code changes.In `_quarto.yml` (applies to all documents in the project):```yamlexecute:freeze: auto # re-execute only when source code changes```In an individual document's YAML:```yamlexecute:freeze:true # never re-execute — always use cached output```Cached output is stored in the `_freeze/` directory. Commit this directory to version control so collaborators can render the document without re-running expensive computations.## The `_quarto.yml` Project File {-}A `_quarto.yml` file in the root of a project configures all documents simultaneously. This is the key advantage of the Quarto project system over R Markdown.### Website Project {-}```yamlproject:type: websiteoutput-dir: docs # rendered output goes here (for GitHub Pages)website:title:"LADAL"navbar:left:-href: index.qmdtext: Home-href: tutorials.qmdtext: Tutorials-href: about.qmdtext: Aboutsidebar:style: dockedcontents:-section:"Text Analysis"contents:-tutorials/freq/freq.qmd-tutorials/string/string.qmdformat:html:theme: cosmotoc:truetoc-depth:3code-fold: showexecute:freeze: autowarning:falsemessage:false```### Book Project {-}```yamlproject:type: bookbook:title:"Quantitative Methods in Linguistics"author:"Martin Schweinberger"date: last-modifiedchapters:-index.qmd-intro.qmd-part:"Part I: Foundations"chapters:-chapters/data.qmd-chapters/freq.qmd-part:"Part II: Modelling"chapters:-chapters/regression.qmd-chapters/mixed.qmd-references.qmdbibliography: references.bibformat:html:theme: cosmopdf:documentclass: bookgeometry: margin=2.5cm```### Shared Format Defaults {-}Any `format:` settings in `_quarto.yml` apply to all documents and can be overridden in individual documents:```yamlformat:html:theme: cosmotoc:truecode-fold: showfig-height:5fig-width:7execute:echo:truemessage:falsewarning:falsecache:falsefreeze: auto```---# Cross-References {#crossref}::: {.callout-note}## Section Overview**What you will learn:** How to label and reference figures, tables, sections, and equations in both R Markdown (via `bookdown`) and Quarto (natively):::## In Quarto {-}Quarto has built-in cross-references. Every referenceable element needs a label with the appropriate prefix.### Figures {-}Label a figure chunk with `#| label: fig-something` and reference it with `@fig-something`:```markdown` ``{r}#| label: fig-vowel-chart#| fig-cap: "Vowel space of the L1-German learner vs. RP native speakers"#| fig-height: 6plot(vowel_chart)` ``The results are shown in @fig-vowel-chart.```For Markdown images:```markdown{#fig-vowel-chart}As shown in @fig-vowel-chart, the learner's vowels are displaced.```### Tables {-}```markdown` ``{r}#| label: tbl-freq#| tbl-cap: "Top 20 words by frequency"freq_table |> flextable()` ``@tbl-freq shows the 20 most frequent words.```### Sections {-}```markdown## Results {#sec-results}See @sec-results for the full discussion.```### Equations {-}```markdown$$F_{\text{Lobanov}} = \frac{F - \bar{F}}{SD_F}$$ {#eq-lobanov}As shown in @eq-lobanov, Lobanov normalisation is a z-score transformation.```### Reference Formatting {-}Quarto formats cross-references automatically: `@fig-vowel-chart` becomes "Figure 1", `@tbl-freq` becomes "Table 1", `@sec-results` becomes "Section 3", and `@eq-lobanov` becomes "Equation 1". The prefix text can be customised in `_quarto.yml`:```yamlcrossref:fig-title:"Figure"tbl-title:"Table"eq-title:"Equation"fig-prefix:"Fig."tbl-prefix:"Tab."```## In R Markdown (via `bookdown`) {-}R Markdown requires the `bookdown` package for cross-references. Use output formats from `bookdown` and the `\@ref()` syntax:```yamloutput:bookdown::html_document2:toc:truebookdown::pdf_document2:toc:true``````markdownSee Figure \@ref(fig:vowel-chart) and Table \@ref(tab:freq-table).(ref:vowel-chart-cap) Vowel space of the L1-German learner vs. RP native speakers.` ``{r vowel-chart, fig.cap="(ref:vowel-chart-cap)"}plot(vowel_chart)` `````---# Citations and Bibliographies {#citations}::: {.callout-note}## Section Overview**What you will learn:** How to manage references with BibTeX; how to cite sources in Markdown; how to specify citation styles with CSL files; and how Quarto's visual editor simplifies citation management:::## BibTeX Reference Files {-}Both R Markdown and Quarto use BibTeX (`.bib`) files for bibliographies. A `.bib` file contains entries like:```bibtex@book{johnson2003acoustic, author = {Johnson, Keith}, title = {Acoustic and Auditory Phonetics}, year = {2003}, publisher = {Blackwell}, address = {Oxford}}@article{lobanov1971classification, author = {Lobanov, B. M.}, title = {Classification of Russian vowels spoken by different speakers}, journal = {Journal of the Acoustical Society of America}, year = {1971}, volume = {49}, number = {2}, pages = {606--608}}@manual{schweinberger2026notebooks, author = {Schweinberger, Martin}, title = {R Markdown and Quarto: Creating Reproducible Documents}, note = {https://ladal.edu.au/tutorials/notebooks/notebooks.html}, year = {2026}, organization = {The Language Technology and Data Analysis Laboratory (LADAL)}, address = {Brisbane}, edition = {2026.03.10}}```Point your document at the `.bib` file:```yamlbibliography: references.bib```## Citation Syntax {-}```markdown[@johnson2003acoustic] # (Johnson 2003)[@johnson2003acoustic, p. 45] # (Johnson 2003, p. 45)[@johnson2003acoustic; @lobanov1971] # (Johnson 2003; Lobanov 1971)@johnson2003acoustic # Johnson (2003) — narrative citation[-@johnson2003acoustic] # (2003) — suppress author name```**Rendered examples:**- Parenthetical: formants are described in detail in [@johnson2003acoustic]- Narrative: @johnson2003acoustic provides a thorough introduction to formant analysis- Page reference: the measurement procedure follows [@johnson2003acoustic, p. 45]- Suppressed author: as noted previously ([-@johnson2003acoustic])## Citation Style Languages {-}The default citation style is Chicago author-date. To use a different style, download a CSL file from the [Zotero Style Repository](https://www.zotero.org/styles) and point your document at it:```yamlcsl: unified-style-linguistics.csl``````{r csl_table, echo=FALSE, message=FALSE, warning=FALSE}data.frame( Style = c("Chicago author-date", "APA 7th edition", "MLA 9th edition", "Unified Style Sheet for Linguistics", "Journal of the International Phonetic Association", "Language"), `CSL filename` = c( "`chicago-author-date.csl`", "`apa.csl`", "`modern-language-association.csl`", "`unified-style-linguistics.csl`", "`journal-of-the-international-phonetic-association.csl`", "`language.csl`" ), `Common use` = c( "Humanities default", "Psychology, education, social sciences", "Literature, cultural studies", "General linguistics journals", "Phonetics and phonology", "Linguistics Society of America journals" ), check.names = FALSE) |> flextable() |> flextable::set_table_properties(width = 1, layout = "autofit") |> flextable::theme_zebra() |> flextable::fontsize(size = 10) |> flextable::set_caption("Common CSL citation styles for linguistics")```## The Reference List {-}Pandoc automatically inserts the formatted reference list at the end of the document. In Quarto, add a `# References {-}` heading at the bottom; in R Markdown, the list appears after the last section or after `# References`.To place the reference list somewhere other than the end of the document, use a div:```markdown::: {#refs}:::```## Quarto Visual Editor and Zotero Integration {-}Quarto's Visual Editor (switch via the **Source/Visual** toggle in RStudio) provides a GUI for inserting citations. It integrates with:- **Zotero** (via the Zotero connector) — search your Zotero library and insert citations by clicking- **DOI lookup** — paste a DOI and Quarto fetches the bibliographic data automatically- **CrossRef search** — search published literature by title or authorThe visual editor automatically adds new entries to your `.bib` file and inserts the citation key in the document.---# Parameterised Reports {#params}::: {.callout-note}## Section Overview**What you will learn:** How to use YAML parameters to create one document template that generates multiple outputs — for example, one report per speaker, corpus, or time period:::## Defining Parameters {-}Parameters are defined in the YAML header and accessed in R code via `params$name`:**R Markdown:**```yamltitle:"Vowel Chart Report: MY_SPEAKER" # use params$speaker here in practiceparams:speaker:"ms"variety:"RP"max_formant:5500```**Quarto:**```yamltitle:"Vowel Chart Report"params:speaker:"ms"variety:"RP"max_formant:5500```In both cases, access the parameters in code chunks with `params$speaker`, `params$variety`, etc.## Using Parameters in Code {-}```{r params_example, eval=FALSE}# Filter data to the speaker specified in paramsspeaker_data <- voweldata |> dplyr::filter(subject == params$speaker)# Use the variety name in a plot titleggplot(speaker_data, aes(x = F2, y = F1)) + geom_text(aes(label = ipa)) + labs(title = paste("Vowel space —", params$variety, "variety"))```## Rendering Multiple Reports {-}To generate one report per speaker programmatically:```{r batch_render, eval=FALSE}speakers <- c("ms", "jb", "ak", "lr")purrr::walk(speakers, function(spk) { rmarkdown::render( input = "vowel_report.Rmd", output_file = paste0("reports/", spk, "_vowels.html"), params = list(speaker = spk) )})```For Quarto, use `quarto::quarto_render()` with the `execute_params` argument:```{r batch_quarto, eval=FALSE}purrr::walk(speakers, function(spk) { quarto::quarto_render( input = "vowel_report.qmd", output_file = paste0("reports/", spk, "_vowels.html"), execute_params = list(speaker = spk) )})```---# Reproducibility Best Practices {#reproducibility}::: {.callout-note}## Section Overview**What you will learn:** Concrete practices for making your R Markdown and Quarto documents maximally reproducible — for yourself, your collaborators, and your readers:::## Always Include `sessionInfo()` {-}R package versions change. A script that works with `ggplot2` 3.4.0 may behave differently with 3.5.0. Always include `sessionInfo()` at the end of your document so readers can see exactly which package versions were used:```{r session_practice, eval=FALSE}sessionInfo()```## Set a Random Seed {-}Any analysis involving random numbers (simulation, bootstrapping, random train/test splits, k-means clustering) must set a seed for reproducibility:```{r seed_practice, eval=FALSE}set.seed(2026)```Place `set.seed()` at the top of your setup chunk or immediately before the relevant analysis.## Use `here::here()` for File Paths {-}Absolute file paths (e.g. `C:/Users/martin/Documents/project/data.csv`) break when the project is moved or shared. Use `here::here()` to construct paths relative to the project root:```{r here_practice, eval=FALSE}library(here)data <- read.csv(here("data", "corpus.csv"))```## Pin Package Versions with `renv` {-}The `renv` package creates a project-specific library with pinned package versions, so the project can be restored exactly on any machine:```{r renv_practice, eval=FALSE}# Initialise renv in your projectrenv::init()# After installing/updating packages, snapshot the libraryrenv::snapshot()# Collaborator restores exact package versionsrenv::restore()```## Avoid Absolute Dates {-}Use `date: last-modified` (Quarto) or `date: "YYYY-MM-DD"` set via `Sys.Date()` as an inline R expression (R Markdown) rather than a hardcoded date string — the document date always reflects when it was last rendered.## Use Version Control {-}Store your `.Rmd`/`.qmd`, `.bib`, data files, and `renv.lock` in a Git repository. This makes every change traceable and enables collaboration via GitHub or GitLab.```{r reproducibility_table, echo=FALSE, message=FALSE, warning=FALSE}data.frame( Practice = c( "Include `sessionInfo()`", "Set `set.seed()`", "Use `here::here()` paths", "Use `renv` for package management", "Use version control (Git)", "Use `freeze: auto` in Quarto", "Cache expensive chunks with `cache: true`", "Use `embed-resources: true` for HTML", "Write `echo: true` for analytical chunks", "Document all data sources" ), Why = c( "Records exact package versions used", "Ensures random results are reproducible", "File paths work on any machine", "Pins package versions for exact reproducibility", "Tracks changes; enables collaboration", "Avoids re-running unchanged code on project rebuild", "Speeds up rendering for expensive computations", "Self-contained file — no broken relative links", "Readers can verify and reproduce the analysis", "Provenance of data is clear and traceable" ), check.names = FALSE) |> flextable() |> flextable::set_table_properties(width = 1, layout = "autofit") |> flextable::theme_zebra() |> flextable::fontsize(size = 10) |> flextable::set_caption("Reproducibility best practices for R Markdown and Quarto documents")```---# Common Problems and Solutions {#troubleshooting}::: {.callout-note}## Section Overview**What you will learn:** The most common errors encountered when rendering R Markdown and Quarto documents, and how to fix them:::```{r troubleshooting_table, echo=FALSE, message=FALSE, warning=FALSE}data.frame( Problem = c( "Document fails to render with a LaTeX error", "Unicode/IPA symbols appear as boxes or ? in PDF", "Figures not showing in PDF", "`object 'x' not found` error", "Package not found error during render", "YAML parsing error", "Cross-reference not resolving (`@fig-X` shows literally)", "Cache not updating after data change", "HTML output has broken images", "Chunk option has no effect" ), Cause = c( "Missing LaTeX package or TinyTeX not installed", "`pdflatex` engine does not support Unicode", "File path is wrong or figure is not generated", "Chunk that creates the object ran after the chunk that uses it", "Package installed in global library but not in `renv` library", "Incorrect indentation or special characters in YAML values", "Chunk label missing the `fig-` prefix or wrong syntax", "Cache key is based on code only — data changes are not detected", "Path is absolute or relative to wrong directory", "Option spelled incorrectly or wrong syntax (`.` vs `-`)" ), Solution = c( "Run `tinytex::install_tinytex()` or `tinytex::tlmgr_install('pkg')`", "Set `latex_engine: xelatex` (R Markdown) or `latex-engine: xelatex` (Quarto)", "Check path with `file.exists()`; use `here::here()`", "Reorder chunks so objects are created before they are used", "Run `renv::restore()` or `renv::install('pkg')`", "Wrap values containing colons or special chars in quotes; use spaces not tabs", "Ensure label starts with `fig-` and `#|` syntax is used", "Add `dependson` option pointing to the data-loading chunk", "Use `here::here()` or set `embed-resources: true` in Quarto", "Check spelling: R Markdown uses `.` (e.g. `fig.height`); Quarto uses `-` (e.g. `fig-height`)" ), check.names = FALSE) |> flextable() |> flextable::set_table_properties(width = 1, layout = "autofit") |> flextable::theme_zebra() |> flextable::fontsize(size = 9.5) |> flextable::set_caption("Common rendering problems and their solutions")```---# Citation and Session Info {-}Schweinberger, Martin. 2026. *R Markdown and Quarto: Creating Reproducible Documents*. Brisbane: The Language Technology and Data Analysis Laboratory (LADAL). url: https://ladal.edu.au/tutorials/notebooks/notebooks.html (Version 2026.03.10).```@manual{schweinberger2026notebooks, author = {Schweinberger, Martin}, title = {R Markdown and Quarto: Creating Reproducible Documents}, note = {https://ladal.edu.au/tutorials/notebooks/notebooks.html}, year = {2026}, organization = {The Language Technology and Data Analysis Laboratory (LADAL)}, address = {Brisbane}, edition = {2026.03.10}}``````{r session_info}sessionInfo()```::: {.callout-note}## AI Transparency StatementThis tutorial was written with the assistance of **Claude** (claude.ai), a large language model created by Anthropic. Claude was used to substantially expand and restructure a shorter existing LADAL tutorial on R Notebooks and Markdown. All content was reviewed and approved by Martin Schweinberger, who takes full responsibility for its accuracy.:::---[Back to top](#intro)[Back to LADAL home](/)---# References {-}