Embedding Computations & Code
Session 3
Session Overview
Session 3: Embedding Computations & Code
- Computing Environments
- Setup R, Python, and Julia for Quarto.
- Engine configuration and code cell structure.
- Understanding multi-language workflows.
- Execution Options
- Code cell options using comment + pipe syntax.
- Control code visibility, evaluation, and output.
- Global execution settings in YAML.
- Cache and Freeze
- Cache for development speed vs freeze for collaboration.
- Understanding Jupyter and Knitr caching systems.
- CLI commands for cache and freeze management.
- Parameters
- Creating dynamic document variations.
- Defining parameters in Python and R.
- Command-line parameter passing and YAML files.
Session Objectives
This session explores Quarto’s computational capabilities, focusing on seamless multi-language workflows, code cell options, and integration patterns for R and Python data science stacks.
Learning Objectives
By the end of this session, participants will be able to:
- Execute R
, Python , Julia code. - Configure code cells using “comment symbol” + “pipe” (
|) syntax. - Control code visibility and execution.
- Cache computations for improved performance.
Computing Environments
Setup R, Python, and/or Julia for Quarto
r
# Install renv if not already installed
install.packages("renv")
# Initialise project
renv::init()
# Install packages
renv::install("rmarkdown")
# Save current state
renv::snapshot()bash
# Install uv (if not installed)
pip install uv
# Initialise project
uv init --no-package --vcs none
# Create virtual environment
uv venv
# Activate environment
source .venv/bin/activate
# Add packages
uv add jupyter papermilljulia
# Start Julia in your project directory
using Pkg
# Activate current directory as project
Pkg.activate(".")
# Add packages
Pkg.add("IJulia")
# Instantiate environment
Pkg.instantiate()Engine Configuration
Configure engines in your document header:
knitrjupyterjulia
yaml
---
engine: knitr
---yaml
---
engine: jupyter
jupyter: python3
---yaml
---
engine: julia
---Set explicitly the engine in your document header instead of relying on auto-detection which does not work for inline code (i.e., `{language} ...`).
What is a Code Cell?
A code cell (also called a code chunk) is a section of executable code (defined by ```{language}) embedded within your Quarto document.
Code cells allow you to:
- Execute programming code directly in your document.
- Display both the code and its output.
- Create reproducible analyses and reports.
Code Cell Structure
qmd
- 1
-
Computing language (e.g.,
python,r,julia). - 2
-
Code cell options (e.g.,
label,echo,eval). - 3
- Code content (your actual programming code).
Why Use Code Cells?
Reproducibility
- Code and results stay together.
- Easy to re-run analyses.
- Version control friendly.
Documentation
- Combine narrative and code.
- Show methodology clearly.
- Create living documents.
Execution Options
Setting Execution Options Globally
yaml
execute:
...execute options
| Option | Description |
|---|---|
eval |
Evaluate the code chunk (if false, just echos the code into the output). |
echo |
Include the source code in output |
output |
Include the results of executing the code in the output (true, false, or asis to indicate that the output is raw markdown and should not have any of Quarto’s standard enclosing markdown). |
warning |
Include warnings in the output. |
error |
Include errors in the output (note that this implies that errors executing code will not halt processing of the document). |
include |
Catch all for preventing any output (code or results) from being included (e.g., include: false suppresses all output from the code block). |
renderings |
Specify rendering names for the plot or table outputs of the cell, e.g., [light, dark]. See Renderings. |
Code Cells Options
The “comment symbol” + “pipe” (|) syntax allows to pass options to code cells.
Code Visibility Control:
- 1
- Hide code, show output.
- 2
- Show code, don’t execute.
- 3
- Execute code, hide everything.
- 4
- Collapsible code blocks.
Output Control:
- 1
- Suppress warnings
- 2
- Suppress messages
- 3
- Show errors for debugging
- 4
- Hide all output
Cache and Freeze
Two Systems
Cache: Stores computation results
- Speeds up development.
- Works during iteration.
- Engine-specific behaviour.
Freeze: Prevents re-execution
- Enables collaboration.
- Project-wide control.
- Version control friendly.
Cache: Development Speed
Store expensive computation results to avoid re-running during development.
yaml
execute:
cache: trueTwo Types:
- Jupyter Cache: Document-level (all-or-nothing).
- Knitr Cache: Cell-level (granular control).
Freeze: Collaboration Control
Prevent documents from re-executing during project renders.
Results saved in _freeze directory (commit to version control).
yaml
execute:
freeze: auto # Re-render only when source changes
freeze: true # Never re-render during project renderKey Behavioural Differences
| Action | Cache | Freeze |
|---|---|---|
| Individual document render | ✅ Used | ❌ Ignored |
| Project render | ✅ Used | ✅ Controls execution |
| Prose changes | No effect | No effect |
| Code changes | Invalidates cache | Triggers re-render (auto mode) |
When to Use Each
Use Cache When
- Developing multi format documents.
- Iterating on analysis.
- Working with expensive computations.
- Editing prose frequently.
Use Freeze When
- Working in teams.
- Managing large projects.
- Environment setup is complex.
- Results need to be reproducible.
Essential CLI Commands
Cache Control
bash
quarto render --cache # Force cache use
quarto render --no-cache # Disable cache
quarto render --cache-refresh # Force refreshFreeze Management
bash
quarto render document.qmd # Always executes (ignores freeze)
quarto render # Respects freeze settingsGolden Rules
- Cache for Development.
Use when iterating on individual documents.
- Freeze for Collaboration.
Use when working with teams or managing large projects.
- Different Scopes.
- Cache: Session-level performance.
- Freeze: Project-level workflow management.
- Version Control.
Always commit_freezedirectory contents.
Parameters
What Are Parameters?
Parameters allow you to create dynamic variations of the same document:
- Geographic reports → Different locations
- Time-based analysis → Different periods
- Scenario modelling → Different assumptions
- Multi-client reports → Different datasets
Think of parameters as variables that make your documents code reusable and flexible.
Defining Parameters
python
#| tags: [parameters]
alpha = 0.1
ratio = 0.5
country = "UK"
year = 2024- Must use
#| tags: [parameters]comment. - Provide sensible default values.
- Parameters available in top-level environment.
- Works with
.qmdand.ipynbfiles.
yaml
---
title: "Sales Report"
params:
region: "North"
start_date: "2024-01-01"
threshold: 1000
---Access in R code:
r
print(params[["region"]])Passing Parameters: Command Line
Use the -P (--execute-param) flag to override parameter values:
bash
# Single parameter
quarto render report.qmd --execute-param country:France
# Multiple parameters
quarto render report.qmd -P year:2023 -P region:Europe
# With output specification
quarto render report.qmd -P country:Germany --to typstPassing Parameters: YAML Files
Create reusable parameter sets with YAML files:
params.yml
country: "Spain"
year: 2023
budget: 50000Terminal
quarto render report.qmd \
--execute-params params.ymlVersion control, team sharing, complex configurations.
Practical Example
Setup (Jupyter/Python)
markdown
```{python}
#| tags: [parameters]
region = "All"
quarter = "Q1"
min_sales = 1000
```Using parameters
markdown
```{python}
if region != "All":
df = df[df['region'] == region]
df_filtered = df[df['sales'] >= min_sales]
title = f"{region} Sales - {quarter}"
```Command line usage
bash
quarto render sales.qmd \
--execute-param region:North \
--execute-param quarter:Q2Customised report for North region, Q2 data.
Best Practices
✅ Do
- Provide meaningful defaults.
- Use descriptive names.
- Document parameter types.
- Validate values in code.
- Use YAML for complex configs.
❌ Avoid
- Generic names (
x,val). - Parameters without defaults.
- Hardcoded values.
- Overly complex structures.
Workflow Integration
Automated reporting
bash
# Daily reports
quarto render report.qmd -P date:"$(date +%Y-%m-%d)"
# Multiple outputs
for region in North South East West; do
quarto render regional.qmd -P region:$region
doneCI/CD pipelines, batch processing, scheduled reports.
Hands-On Exercise: Adding Computational Power to Your Portfolio
Exercise Overview
Objective: Transform your Session 2 portfolio document into a computational showcase by adding live code execution, demonstrating the power of embedding computations in Quarto documents using modern Python tools.
Example Code:
bash
tar -xzf "03-exercises.tar.gz" -C "03-embedding-computations-code"Part 1: Environment Setup
Choose your language and update your YAML header:
yaml
---
title: "My Computational Portfolio"
author: "Your Name"
engine: jupyter
jupyter: python3
execute:
echo: true
warning: false
---Install packages:
bash
uv add polars plotnine # pip install polars plotnineyaml
---
title: "My Computational Portfolio"
author: "Your Name"
engine: knitr
execute:
echo: true
warning: false
---Install packages:
r
install.packages(c("dplyr", "ggplot2"))yaml
---
title: "My Computational Portfolio"
author: "Your Name"
engine: julia
execute:
echo: true
warning: false
---Install packages:
julia
using Pkg
Pkg.add(["DataFrames", "Plots", "StatsPlots"])Part 2: Replace Static with Dynamic
Replace your skills table from Session 2:
- Create a Polars
DataFramewith your skills data. - Include columns: skill name, confidence level, hours practiced.
- Use
print()to display the data nicely. - Calculate total practice hours with
pl.sum(). - Show the result using inline code
`{python} your_calculation`.
- Create a
data.framewith your skills data. - Include columns: skill name, confidence level, hours practiced.
- Use
knitr::kable()to display the table nicely. - Calculate total practice hours with
sum(). - Show the result using inline code
`{r} your_calculation`.
- Create a
DataFramewith your skills data. - Include columns: skill name, confidence level, hours practiced.
- Display the
DataFramedirectly. - Calculate total practice hours with
sum(). - Show the result using inline code
`{julia} your_calculation`.
Part 3: Create Your First Visualization
Make a chart of your skills:
- Use plotnine to create a bar chart.
- Try
geom_col()orgeom_bar(). - Add proper labels with
labs(). - Use
theme_minimal()for clean styling. - Add a figure caption with
#| fig-cap:.
- Use ggplot2 to create a bar chart.
- Try
geom_col()orgeom_bar(). - Add proper labels with
labs(). - Use
theme_minimal()for clean styling. - Add a figure caption with
#| fig-cap:.
- Use Plots.jl to create a bar chart.
- Try
bar()function. - Add proper labels with
xlabel!()andylabel!(). - Add a title with
title!(). - Add a figure caption with
#| fig-cap:.
Part 4: Experiment with Code Visibility
Try different code cell options:
- Create a cell with
#| eval: false(shows code, doesn’t run). - Make a collapsible section with
#| code-fold: true. - Hide code with
#| echo: falsebut show output. - Use
#| include: falsefor data setup.
- Create a cell with
#| eval: false(shows code, doesn’t run). - Make a collapsible section with
#| code-fold: true. - Hide code with
#| echo: falsebut show output. - Use
#| include: falsefor library loading.
- Create a cell with
#| eval: false(shows code, doesn’t run). - Make a collapsible section with
#| code-fold: true. - Hide code with
#| echo: falsebut show output. - Use
#| include: falsefor package imports.
Success Criteria
✅ You’ve successfully completed the exercise if you can:
- Transform static content into dynamic, computed content using Python
, R , or Julia . - Create and display data visualisations.
- Use inline code to insert computed values into prose.
- Experiment with different code cell visibility options.