df <- read_csv(
"/Users/ewan/Documents/data/study.csv"
)King’s Open Research Summer School
July 21, 2026
My aim is to surface key tools and habits — you’ll need to explore further on your own.
Reproducibility is necessary for open science, but not sufficient. Broader change in motivations, incentives, and culture is essential.
“Research can be open and reproducible and still completely and obviously wrong.”
Richard McElreath (2025)
1. Code and data hygiene
2. Version control with Git
3. Managing your environment
4. Workflow automation
5. Dynamic reporting with Quarto
6. Wrap-up
final_final_v3.csvdata/raw/YYYY-MM-DDUse a consistent project structure
They only work on your computer, right now.
If you move this project, or share it with someone else, paths may break.
Your collaborator does not have your computer.

Never set the working directory inside a script.
Set a project root (i.e., a top-level directory) from:
.here file)Then, construct relative paths with here():
This works well with RStudio projects.
Write modular code:
functions.RFollow a style guide and use a code formatter.
Document with inline comments and README.md files.
Be consistent
Use clear snake_case object names
Objects are nouns; functions are verbs
Give files meaningful, sortable names
Load packages together at the start
Use whitespace to show structure
Organise scripts into clear sections
Break up long, complex expressions
Turn repeated work into functions
Comment the why, not the what
See style.tidyverse.org for details.
From the Code menu, select “Reformat Selection”:
Use git.
Local repository
The working copy on your computer. You can edit files and commit offline.
Remote repository
A linked copy hosted online (e.g., GitHub), holding the full history.
We send and receive changes between them — this is pushing and pulling.
You can use Git entirely locally, without GitHub.
Initialise the repository:
Then on GitHub, create a new repository and connect the remote repository to your local one:
Push your changes to GitHub
Then, repeat:
Some tips for working with Git…
README.md fileA good README.md helps others (and your future self) understand your project.
Your message should explain what changed and why.
🚀 Good
sex to a factor so lm() doesn’t treat it as numeric🔥 Bad
Your message should complete the sentence “If applied, this commit will…”
.gitignore to exclude filesCreate a .gitignore to keep files out of version control:
README, config files.Never commit patient data
Researchers using UK Biobank data committed data folders locally, pushed them to GitHub, and then exposed them publicly.
The Guardian, 14 March 2026
Add data folders to .gitignore file before any data files are added.
Deleting a file later is not enough — the earlier version stays in the Git history.
We need a way of capturing the state of your computing environment, such that you or others can recreate it later.
renvrenv is an R package to manage and reproduce the exact package versions used in a project.
renvFirst, install the package (once):
Save the current state:
Then share renv.lock with collaborator (via Git).
renv lockfileWhen re-initialising a project (e.g., on a new computer, or as a collaborator):
R packages are just one part of
your computing environment.
Containers package your entire computing environment so it runs consistently everywhere.
This typically involves Docker or Singularity.

Dockerfile is a reciperenv.lock into the container to set package versions.renv environment to install those versions.source()Create a script that runs your other scripts:
Make runs only the parts of your code that need updating.
Once your Makefile is defined, run:
Make checks timestamps and re-runs only the steps whose inputs have changed.
targetstargets builds reproducible workflows from R functions and the objects they return, rather than scripts and files.
It tracks changes by content (rather than timestamps) so nothing is recomputed unnecessarily.
Combine code, results, and prose into one document.
---
title: "Bill length and body mass in Adélie penguins"
author: "Ewan Carr"
date: today
format:
html:
toc: true
docx: default
bibliography: references.bib
---
```{r}
#| label: setup
#| include: false
library(tidyverse)
library(palmerpenguins)
adelie <- filter(penguins, species == "Adelie")
```
## Introduction
Bill morphology varies with body size across the *Pygoscelis* genus
[@gorman2014]. Here we look at Adélie penguins only.
## Methods
We fitted a linear model to `r nrow(adelie)` birds.
```{r}
#| label: fig-scatter
#| fig-cap: "Bill length against body mass."
#| warning: false
ggplot(adelie, aes(bill_length_mm, body_mass_g)) +
geom_point(alpha = 0.6) +
geom_smooth(method = "lm") +
labs(x = "Bill length (mm)", y = "Body mass (g)")
```
## Results
Heavier birds had longer bills (@fig-scatter). The full model is
reported in @tbl-model.
```{r}
#| label: tbl-model
#| tbl-cap: "Linear model of body mass on bill length."
#| echo: false
lm(body_mass_g ~ bill_length_mm, data = adelie) |>
broom::tidy() |>
knitr::kable(digits = 2)
```
## References
::: {#refs}
:::Writing
code, linksFigures and tables
Scholarly features
.bib fileOutput formats

Thank you for listening.
Slides and practical materials