8  Data Science Tools for Reporting

8.1 Documentation and Reporting Tools

As a data scientist, sharing your findings clearly is just as important as the analysis itself. Now that we have our analytics platforms set up, let’s explore tools for creating reports, documentation, and presentations.

8.1.1 Markdown: The Foundation of Documentation

Markdown is a lightweight markup language that’s easy to read and write. It forms the basis of many documentation systems.

Markdown’s simplicity and widespread support have made it the de facto standard for documentation in data science projects.

8.1.1.1 Basic Markdown Syntax

# Heading 1
## Heading 2
### Heading 3

**Bold text**
*Italic text*

[Link text](https://example.com)

![Alt text for an image](image.jpg)

- Bullet point 1
- Bullet point 2

1. Numbered item 1
2. Numbered item 2

Table:
| Column 1 | Column 2 |
|----------|----------|
| Cell 1   | Cell 2   |

> This is a blockquote

`Inline code`

```python
# Code block
print("Hello, world!")
```

The language name after the opening backticks is optional and only controls syntax highlighting. Later in this chapter you’ll see fences written as ```{python} with braces — that is Quarto and R Markdown’s own extension, marking a block as code to execute instead of merely display. Plain Markdown has no such concept.

Markdown is designed to be readable even in its raw form. The syntax is intuitive — for example, surrounding text with asterisks makes it italic, and using hash symbols creates headings of different levels.

Many platforms interpret Markdown, including GitHub, Jupyter notebooks, and the documentation tools we’ll discuss next.

8.1.2 R Markdown

R Markdown combines R code, output, and narrative text in a single document that can be rendered to HTML, PDF, Word, and other formats.

The concept of “literate programming” behind R Markdown was first proposed by Donald Knuth in 1984 (Knuth 1984), and it has become a cornerstone of reproducible research in data science.

8.1.2.1 Installing and Using R Markdown

If you’ve installed R and RStudio as described earlier, R Markdown is just a package installation away:

install.packages("rmarkdown")

To create your first R Markdown document:

  1. In RStudio, go to File → New File → R Markdown
  2. Fill in the title and author information
  3. Choose an output format (HTML, PDF, or Word)
  4. Click “OK”

RStudio creates a template document with examples of text, code chunks, and plots, so you don’t start from scratch.

A typical R Markdown document consists of three components:

  1. YAML Header: The block fenced by --- at the top, holding metadata like title, author, and output format. YAML is a plain-text format of key: value settings, with indentation indicating nesting; you’ll meet it again in Docker Compose files and GitHub Actions workflows
  2. Text: Written in Markdown for narratives, explanations, and interpretations
  3. Code Chunks: R code that can be executed to perform analysis and create outputs

For example:

---
title: "My First Data Analysis"
author: "Your Name"
date: "2026-04-30"
output: html_document
---

# Introduction

This analysis explores the relationship between variables X (carat) and Y (price).

## Data Import and Cleaning

```{r setup, eval=FALSE}
# load the diamonds dataset from ggplot2
data(diamonds, package = "ggplot2")

# Create a smaller sample of the diamonds dataset
set.seed(123)  # For reproducibility
my_data <- diamonds |>
  dplyr::slice_sample(n = 1000) |>
  dplyr::select(
    X = carat,
    Y = price,
    cut = cut,
    color = color,
    clarity = clarity
  )

# Display the first few rows
head(my_data)
```

## Data Visualization

```{r visualization, eval=FALSE}
ggplot2::ggplot(my_data, ggplot2::aes(x = X, y = Y)) +
  ggplot2::geom_point() +
  ggplot2::geom_smooth(method = "lm") +
  ggplot2::labs(title = "Relationship between X and Y")
```
Note

Note that we’ve used the namespace convention (package::function()) in the code above rather than loading each package with library(). This is a matter of preference, but benefits include:

  • Avoids loading the full package with library()
  • Prevents naming conflicts (e.g. dplyr::filter() vs. stats::filter())
  • Keeps dependencies explicit and localised right next to each call

For the same reason the pipe above is |>, R’s native pipe, which is part of base R since version 4.1 and needs no package. The older %>% comes from magrittr and requires library(dplyr) or library(magrittr) first.

When you click the “Knit” button in RStudio, the R code in the chunks is executed, and the results (including plots and tables) are embedded in the output document. Code, results, and narrative live in one file, so there is no step where a number is copied from a console into a paragraph and then goes stale. If your data changes, re-knit the document and every figure and table updates.

R Markdown has become a standard in reproducible research because it creates a direct connection between your data, analysis, and conclusions. This connection makes your work more transparent and reliable, as anyone can follow your exact steps and see how you reached your conclusions.

8.1.3 Jupyter Notebooks for Documentation

We’ve already covered Jupyter notebooks for Python development, but they double as documentation tools. Like R Markdown, they combine code, output, and narrative text.

8.1.3.1 Exporting Jupyter Notebooks

Jupyter notebooks can be exported to various formats:

  1. In JupyterLab or Notebook 7, go to File → Save and Export Notebook As
  2. Choose from options like HTML, PDF, Markdown, etc.

Alternatively, you can use nbconvert from the command line:

jupyter nbconvert --to html my_notebook.ipynb

The ability to export notebooks is particularly valuable because it allows you to write your analysis once and then distribute it in whatever format your audience needs. For example, you might use the PDF format for a formal report to stakeholders, HTML for sharing on a website, or Markdown for including in a GitHub repository.

8.1.3.2 Jupyter Book

For larger documentation projects, Jupyter Book builds on the notebook format to create complete books:

# Install Jupyter Book
pip install jupyter-book

# Create a project and start a live-reloading preview
jupyter book start

Jupyter Book organises multiple notebooks and markdown files into a book with navigation, search, and cross-references — useful for multi-page documentation, tutorials, or course materials.

WarningVersion 2 changed the commands

Jupyter Book 2, built on the MyST document engine, is what pip install jupyter-book now gives you, and the command you type — its command-line interface, or CLI — is jupyter book, two words. Version 1’s commands were hyphenated and different: jupyter-book create my-book followed by jupyter-book build my-book/. Most tutorials you’ll find still show the v1 form, which fails with a “command not found” error against a current install.

8.1.4 Quarto: The Next Generation of Literate Programming

Quarto is a newer system that works with both Python and R, unifying the best aspects of R Markdown and Jupyter notebooks.

# Install Quarto CLI from https://quarto.org/docs/get-started/

# Create a new Quarto project (website, book, manuscript, etc.)
quarto create project default my-project

# Or, for a standalone one-off document, simply create a file
# named document.qmd in your editor (no command needed).

# Render a document to HTML (or PDF, docx, etc.)
quarto render document.qmd

Quarto represents an evolution in documentation tools because it provides a unified system for creating computational documents with multiple programming languages. This is particularly valuable if you work with both Python and R, as you can maintain a consistent documentation approach across all your projects.

The key advantage of Quarto is its language-agnostic design — you can mix Python, R, Julia, and other languages in a single document, which reflects the reality of many data science workflows where different tools are used for different tasks.

8.1.4.1 Quarto Dashboards

Since Quarto 1.4 (released in 2024), Quarto can render a document directly into a dashboard layout with rows, columns, value boxes, and tab sets, with no Shiny, Dash, or Streamlit required for the static case. If all you need is a periodic refresh of a dashboard view over your data, this is by far the lightest way to get there: you write a normal .qmd file with a format: dashboard YAML key, and Quarto handles the layout.

---
title: "Sales Overview"
format: dashboard
---
#| title: "Revenue by Quarter"
ggplot(sales, aes(quarter, revenue)) + geom_col()

For interactive behaviour (filters, user inputs), Quarto dashboards can embed Shiny, Observable JS, or even Python/R running in the browser via webR/Pyodide. For readers whose dashboards are read-only and updated nightly, this alone replaces a lot of what used to require a Shiny or Dash server.

8.1.4.2 Parameterised Reports

One of the highest-value Quarto (and R Markdown) features for a business analytics audience is parameterised reports: a single template that you can render with different inputs to produce many tailored outputs. For example, a monthly sales report that takes a region and month parameter and can be rendered once for every region without copy-pasting the document.

---
title: "Sales Report"
format: html
params:
  region: "South Africa"
  month: "2026-03"
---

How you read those values inside the document depends on the engine.

With the knitr engine (R), the YAML block above is all you need — the values arrive in a params list:

cat("Report for", params$region, "covering", params$month)

With the Jupyter engine (Python), Quarto follows papermill’s convention instead: you tag one code cell parameters, assign defaults there as ordinary variables, and refer to them as ordinary variables everywhere else. There is no params object.

#| tags: [parameters]
region = "South Africa"
month = "2026-03"
print(f"Report for {region} covering {month}")

Either way, you render with -P:

quarto render sales.qmd -P region:"EU" -P month:"2026-03"

This single pattern replaces a surprising amount of the ad-hoc “one notebook per client” sprawl that plagues data science teams.

8.1.5 LaTeX for Professional Document Creation

When a report needs to look like a journal article or a formal business document, LaTeX is the typesetting system that gets it there. Markdown handles simple documents well; LaTeX handles precise page layout, mathematical notation, numbered figures and cross-references, and bibliographies.

8.1.5.1 Why LaTeX for Data Scientists?

LaTeX offers several advantages for data science documentation:

  1. Professional typesetting: Produces publication-quality documents with consistent formatting
  2. Math support: Renders complex equations to a typographic standard nothing else matches
  3. Advanced layout control: Provides precise control over document structure and appearance
  4. Bibliography management: Integrates with citation systems like BibTeX
  5. Reproducibility: Separates content from presentation in a plain text format that works with version control

LaTeX documents, particularly those with programmatically generated figures, tend to be more reproducible than those created with proprietary document formats.

8.1.5.2 Getting Started with LaTeX

LaTeX works differently from word processors — you write plain text with special commands, then compile it to produce a PDF. For data science, you don’t need to install a full LaTeX distribution, as Quarto and R Markdown can handle the compilation process.

8.1.5.3 Installing LaTeX for Quarto and R Markdown

The easiest way to install LaTeX for use with Quarto or R Markdown is to use TinyTeX, a lightweight LaTeX distribution:

In R:

install.packages("tinytex")
tinytex::install_tinytex()

In the command line with Quarto:

quarto install tinytex

TinyTeX is designed specifically for R Markdown and Quarto users. It installs only the essential LaTeX packages (around 150MB) compared to full distributions (several GB), and it automatically installs additional packages as needed when you render documents.

8.1.5.4 LaTeX Basics for Data Scientists

Let’s explore the essential LaTeX elements you’ll need for data science documentation:

8.1.5.5 Document Structure

A basic LaTeX document structure looks like this:

\documentclass{article}
\usepackage{graphicx}  % For images
\usepackage{amsmath}   % For advanced math
\usepackage{booktabs}  % For professional tables

\title{Analysis of Customer Purchasing Patterns}
\author{Your Name}
\date{\today}

\begin{document}

\maketitle
\tableofcontents

\section{Introduction}
This report analyses...

\section{Methodology}
\subsection{Data Collection}
We collected data from...

\section{Results}
The results show...

\section{Conclusion}
In conclusion...

\end{document}

When using Quarto or R Markdown, you won’t write this structure directly. Instead, it’s generated based on your YAML header and document content.

8.1.5.6 Mathematical Equations

Mathematical notation is what LaTeX is best at. Here are examples of common equation formats:

Inline equations use single dollar signs:

The model accuracy is $\alpha = 0.95$, which exceeds our threshold.

Display equations use double dollar signs:

$$
\bar{X} = \frac{1}{n} \sum_{i=1}^{n} X_i
$$

Equation arrays for multi-line equations:

\begin{align}
Y &= \beta_0 + \beta_1 X_1 + \beta_2 X_2 + \epsilon \\
&= \beta_0 + \sum_{i=1}^{2} \beta_i X_i + \epsilon
\end{align}

Some common math symbols in data science:

Description LaTeX Code Result
Summation \sum_{i=1}^{n} \(\sum_{i=1}^{n}\)
Product \prod_{i=1}^{n} \(\prod_{i=1}^{n}\)
Fraction \frac{a}{b} \(\frac{a}{b}\)
Square root \sqrt{x} \(\sqrt{x}\)
Bar (mean) \bar{X} \(\bar{X}\)
Hat (estimate) \hat{\beta} \(\hat{\beta}\)
Greek letters \alpha, \beta, \gamma \(\alpha, \beta, \gamma\)
Infinity \infty \(\infty\)
Approximately equal \approx \(\approx\)
Distribution X \sim N(\mu, \sigma^2) \(X \sim N(\mu, \sigma^2)\)

8.1.5.7 Tables

LaTeX can create publication-quality tables. The booktabs package is recommended for professional-looking tables with proper spacing:

\begin{table}[htbp]
\centering
\caption{Model Performance Comparison}
\begin{tabular}{lrrr}
\toprule
Model & Accuracy & Precision & Recall \\
\midrule
Random Forest & 0.92 & 0.89 & 0.94 \\
XGBoost & 0.95 & 0.92 & 0.91 \\
Neural Network & 0.90 & 0.87 & 0.92 \\
\bottomrule
\end{tabular}
\end{table}

8.1.5.8 Figures

To include figures with proper captioning and referencing:

\begin{figure}[htbp]
\centering
\includegraphics[width=0.8\textwidth]{histogram.png}
\caption{Distribution of customer spending by category}
\label{fig:spending-dist}
\end{figure}

As shown in Figure \ref{fig:spending-dist}, the distribution is right-skewed.

8.1.5.9 Using LaTeX with Quarto

Quarto makes it easy to incorporate LaTeX features while keeping your document source readable. Here’s how to configure Quarto for PDF output using LaTeX:

8.1.5.9.1 YAML Configuration

In your Quarto YAML header, specify PDF output with LaTeX options:

---
title: "Analysis Report"
author: "Your Name"
format:
  pdf:
    documentclass: article
    geometry:
      - margin=1in
    fontfamily: libertinus
    colorlinks: true
    number-sections: true
    fig-width: 7
    fig-height: 5
    cite-method: biblatex
    biblio-style: apa
---
8.1.5.9.2 Customising PDF Output

You can further customise the LaTeX template by:

  1. Including raw LaTeX: Use the raw attribute to include LaTeX commands

    ```{=latex}
    \begin{center}
    \large\textbf{Confidential Report}
    \end{center}
    ```
  2. Adding LaTeX packages: Include additional packages in the YAML

    format:
      pdf:
        include-in-header: 
          text: |
            \usepackage{siunitx}
            \usepackage{algorithm2e}
  3. Using a custom template: Create your own template for full control

    format:
      pdf:
        template: custom-template.tex
8.1.5.9.3 Equations in Quarto

Quarto supports LaTeX math syntax directly:

The linear regression model can be represented as:

$$
y_i = \beta_0 + \beta_1 x_i + \epsilon_i
$$

where $\epsilon_i \sim N(0, \sigma^2)$.
8.1.5.9.4 Citations and Bibliography

For managing citations, create a BibTeX file (e.g., references.bib):

@article{knuth84,
  author = {Knuth, Donald E.},
  title = {Literate Programming},
  year = {1984},
  journal = {Comput. J.},
  volume = {27},
  number = {2},
  pages = {97--111}
}

Then cite in your Quarto document:

Literate programming [@knuth84] combines documentation and code.

And configure in YAML:

bibliography: references.bib
csl: ieee.csl  # Citation style

8.1.6 Advanced LaTeX Features for Data Science

8.1.6.1 Algorithm Description

The algorithm2e package helps document computational methods:

\begin{algorithm}[H]
\SetAlgoLined
\KwData{Training data $X$, target values $y$}
\KwResult{Trained model $M$}
Split data into training and validation sets\;
Initialize model $M$ with random weights\;
\For{each epoch}{
    \For{each batch}{
        Compute predictions $\hat{y}$\;
        Calculate loss $L(y, \hat{y})$\;
        Update model weights using gradient descent\;
    }
    Evaluate on validation set\;
    \If{early stopping condition met}{
        break\;
    }
}
\caption{Training Neural Network with Early Stopping}
\end{algorithm}

8.1.6.2 Professional Tables with Statistical Significance

For reporting analysis results with significance levels:

\begin{table}[htbp]
\centering
\caption{Regression Results}
\begin{tabular}{lrrrr}
\toprule
Variable & Coefficient & Std. Error & t-statistic & p-value \\
\midrule
Intercept & 23.45 & 2.14 & 10.96 & $<0.001^{***}$ \\
Age & -0.32 & 0.05 & -6.4 & $<0.001^{***}$ \\
Income & 0.015 & 0.004 & 3.75 & $0.002^{**}$ \\
Education & 1.86 & 0.72 & 2.58 & $0.018^{*}$ \\
\bottomrule
\multicolumn{5}{l}{\scriptsize{$^{*}p<0.05$; $^{**}p<0.01$; $^{***}p<0.001$}} \\
\end{tabular}
\end{table}

8.1.6.3 Multi-part Figures

For comparing visualisations side by side:

\begin{figure}[htbp]
\centering
\begin{subfigure}{0.48\textwidth}
    \includegraphics[width=\textwidth]{model1_results.png}
    \caption{Linear Model Performance}
    \label{fig:model1}
\end{subfigure}
\hfill
\begin{subfigure}{0.48\textwidth}
    \includegraphics[width=\textwidth]{model2_results.png}
    \caption{Neural Network Performance}
    \label{fig:model2}
\end{subfigure}
\caption{Performance comparison of predictive models}
\label{fig:models-comparison}
\end{figure}

8.1.7 LaTeX in R Markdown

If you’re using R Markdown instead of Quarto, the approach is similar:

---
title: "Statistical Analysis Report"
author: "Your Name"
output:
  pdf_document:
    toc: true
    number_sections: true
    fig_caption: true
    keep_tex: true  # Useful for debugging
    includes:
      in_header: preamble.tex
---

The preamble.tex file can contain additional LaTeX packages and configurations:

% preamble.tex
\usepackage{booktabs}
\usepackage{longtable}
\usepackage{array}
\usepackage{multirow}
\usepackage{wrapfig}
\usepackage{float}
\usepackage{colortbl}
\usepackage{pdflscape}
\usepackage{tabu}
\usepackage{threeparttable}
\usepackage{threeparttablex}
\usepackage[normalem]{ulem}
\usepackage{makecell}
\usepackage{xcolor}

8.1.8 Troubleshooting LaTeX Issues

LaTeX can sometimes produce cryptic error messages. Here are solutions to common issues:

8.1.8.1 Missing Packages

If you get an error about a missing package when rendering:

! LaTeX Error: File 'tikz.sty' not found.

TinyTeX normally resolves this for you: when it hits a missing .sty file it looks up which TeX Live package provides it, installs it, and recompiles. That happens by default, so most of the time the error above is one you never see.

When it doesn’t resolve automatically, point TinyTeX at the compilation log and let it work out what’s missing:

tinytex::parse_install("document.log")

Installing by hand is a last resort, and the trap is that the TeX Live package name rarely matches the file name — tikz.sty ships in a package called pgf, not tikz:

tinytex::tlmgr_install("pgf")

8.1.8.2 Figure Placement

If figures aren’t appearing where expected:

\begin{figure}[!htbp]  % The ! makes LaTeX try harder to respect placement

8.1.8.3 Large Tables Spanning Multiple Pages

For large tables that need to span pages:

\begin{longtable}{lrrr}
\caption{Comprehensive Model Results}\\
\toprule
Model & Accuracy & Precision & Recall \\
\midrule
\endhead
% Table contents...
\bottomrule
\end{longtable}

8.1.8.4 PDF Compilation Hangs

If compilation seems to hang, it is usually waiting for input at LaTeX’s interactive error prompt. TinyTeX passes -halt-on-error by default so this is rare, but if you are calling LaTeX yourself, or a package has re-enabled the prompt, force it to fail rather than wait:

# In R
tinytex::latexmk('document.tex', engine_args = '-interaction=nonstopmode')

Then read document.log — the first ! line in that file is the real error.

8.1.9 LaTeX or Typst?

LaTeX has been the standard for scientific documentation for decades. Quarto and R Markdown default to it when you ask for a PDF, which is why it is worth knowing even if you never write a .tex file by hand — and why the errors above are errors you will eventually meet.

It also carries a real learning curve, and for most of what this book’s readers produce, there is now a second option.

8.1.9.1 Typst

Typst is a newer typesetting system aimed at the same output with less ceremony:

Simpler Syntax: Where LaTeX might require complex commands, Typst uses more intuitive markup:

// Typst syntax
= Introduction
== Subsection

$x = (a + b) / c$  // Math notation

#figure(
  image("plot.png"),
  caption: "Sample Plot"
)

Compare this to equivalent LaTeX:

% LaTeX syntax
\section{Introduction}
\subsection{Subsection}

$x = \frac{a + b}{c}$

\begin{figure}
  \includegraphics{plot.png}
  \caption{Sample Plot}
\end{figure}

Faster Compilation: Typst compiles documents significantly faster than LaTeX, making it more suitable for iterative document development.

Better Error Messages: When something goes wrong, Typst provides clearer, more actionable error messages compared to LaTeX’s often cryptic feedback.

Modern Design: Built from the ground up with modern document needs in mind, including better handling of digital-first workflows.

8.1.9.2 Choosing Your Path Forward

For data scientists starting their journey, here’s how to think about these tools:

Choose LaTeX when:

  • Working in academic environments where LaTeX is expected
  • Creating documents with complex mathematical notation
  • Collaborating with teams already using LaTeX workflows
  • You need the ecosystem of specialised packages LaTeX offers

Consider Typst when:

  • You want faster iteration cycles during document development
  • You prefer more modern, readable syntax
  • You’re starting fresh and don’t have legacy LaTeX requirements
  • You want to avoid LaTeX’s steep learning curve

You don’t have to choose up front. Quarto has shipped the Typst compiler since version 1.4, so switching engines is a one-line YAML change and your content stays as it is:

---
title: "Sales Report"
format: typst     # instead of: pdf
---

There is a practical consequence worth stating plainly: format: typst produces a PDF without LaTeX installed at all. If PDF output is all you need, you can skip the TinyTeX installation and everything that follows from it.

8.1.10 Creating Technical Documentation

For more complex projects, specialised documentation tools may be needed:

8.1.10.1 MkDocs: Simple Documentation with Markdown

MkDocs creates a documentation website from Markdown files:

# Install MkDocs
pip install mkdocs

# Create a new project
mkdocs new my-documentation

# Serve the documentation locally
cd my-documentation
mkdocs serve

MkDocs is focused on simplicity and readability. It generates a clean, responsive website from your Markdown files, with navigation, search, and themes — enough for project documentation aimed at users or team members, without a heavier system’s configuration burden.

8.1.10.2 Sphinx: Documentation Generated from Code

Sphinx is the documentation tool the Python ecosystem standardised on:

# Install Sphinx
pip install sphinx

# Create a new documentation project
sphinx-quickstart docs

# Build the documentation
cd docs
make html

Sphinx offers advanced features like automatic API documentation generation, cross-referencing, and multiple output formats. It’s the system behind the official documentation for Python itself and many major libraries like NumPy, pandas, and scikit-learn.

Sphinx became the standard for Python documentation largely because it generates reference documentation from docstrings — the descriptive text you write inside a function or class, which Python keeps attached to the object at runtime. You document each function where it lives, and Sphinx extracts and formats those descriptions into a browsable reference that can’t drift out of step with the code.

8.2 Reproducible Reports — Working with Data

When using external data files in Quarto projects, it’s important to understand how to handle file paths properly to ensure reproducibility across different environments.

8.2.1 Common Issues with File Paths

The error 'my_data.csv' does not exist in current working directory is a common issue when transitioning between different editing environments like VS Code and RStudio. This happens because:

  1. Different IDEs may have different default working directories
  2. Quarto’s rendering process often sets the working directory to the chapter’s location
  3. Absolute file paths won’t work when others try to run your code

8.2.2 Project-Relative Paths with the here Package

The here package provides an elegant solution by creating paths relative to your project root:

library(tidyverse)
library(here)

# Load data using project-relative path
data <- read_csv(here("data", "my_data.csv"))
head(data)

The here() function automatically detects your project root (usually where your .Rproj file is located) and constructs paths relative to that location. This ensures consistent file access regardless of:

  • Which IDE you’re using
  • Where the current chapter file is located
  • The current working directory during rendering

To implement this approach:

  1. Create a data folder in your project root
  2. Store all your datasets in this folder
  3. Use here("data", "filename.csv") to reference them

8.2.3 Alternative: Built-in Datasets

For maximum reproducibility, consider using built-in datasets that come with R packages:

# Load a dataset from a package
data(diamonds, package = "ggplot2")

# Display the first few rows
head(diamonds)

Using built-in datasets eliminates file path issues entirely, as these datasets are available to anyone who has the package installed. This is ideal for examples and tutorials where the specific data isn’t crucial.

8.2.4 Creating Sample Data Programmatically

Another reproducible approach is to generate sample data within your code:

# Create synthetic data
set.seed(0491)  # For reproducibility
synthetic_data <- tibble(
  id = 1:20,
  value_x = rnorm(20),
  value_y = value_x * 2 + rnorm(20, sd = 0.5),
  category = sample(LETTERS[1:4], 20, replace = TRUE)
)

# Display the data
head(synthetic_data)

This approach works well for illustrative examples and ensures anyone can run your code without any external files.

8.2.5 Remote Data with Caching

For real-world datasets that are too large to include in packages, you can fetch them from reliable URLs:

# URL to a stable dataset (ggplot2's default branch is 'main', not 'master')
url <- "https://raw.githubusercontent.com/tidyverse/ggplot2/main/data-raw/diamonds.csv"

# Download and read the data
remote_data <- readr::read_csv(url)

# Display the data
head(remote_data)

The cache: true option tells Quarto to save the results and only re-execute this chunk when the code changes, which prevents unnecessary downloads.

8.2.6 Best Practices for Documentation

Effective documentation follows certain principles:

  1. Start early: Document as you go, instead of leaving it to the end
  2. Be consistent: Use the same style and terminology throughout
  3. Include examples: Show how to use your code or analysis
  4. Consider your audience: Technical details for peers, higher-level explanations for stakeholders
  5. Update regularly: Keep documentation in sync with your code

Documenting your work also sharpens your own thinking. Explaining a modelling choice in prose is a reliable way to discover that you can’t justify it.

8.3 Conclusion

This chapter has walked through the document side of data science output: Markdown and Quarto for literate programming, LaTeX (and newer alternatives like Typst) for publication-quality typesetting, parameterised reports for templating, and reproducible data-loading patterns so your reports can be rendered from any machine.

By the end of this chapter you should have:

  • One .qmd document that renders to HTML, containing both prose and a code chunk whose output appears in the result
  • The same document rendered to PDF, with TinyTeX installed — or Typst configured instead, if you’d rather not install a LaTeX distribution at all
  • A report that loads its data by a path that works on someone else’s machine, using here() or an equivalent, rather than an absolute path from yours
  • At least one parameterised render, so you’ve seen the same document produce two different outputs from the same source

What we haven’t covered yet are the charts that live inside these documents and the interactive applications that extend beyond them:

  • The Data Visualisation chapter covers the static and lightly-interactive plotting libraries you’ll embed in reports (matplotlib, seaborn, plotly, ggplot2), plus Mermaid for code-based diagrams.
  • The Web Development for Data Scientists chapter covers the tools for when “rerun the render” isn’t enough and stakeholders need to poke at the data themselves: Shiny, Dash, Streamlit, and Flask.

Together these three chapters form a progression: from static documents that communicate findings, to visualisations that make those findings immediate, to interactive applications that invite exploration.