Will your code work in 2036?

Richard J Telford

23 October 2026

Data + code != reproducible

Data + code + environment = reproducible

Everything Changes,
your code changes not

R changes

R < 3.6.0

set.seed(1)
sample(LETTERS, size = 1)
[1] "G"

R >= 3.6.0

set.seed(1)
sample(LETTERS, size = 1)
[1] "Y"

Packages Change

library(ggplot2)

ggplot(penguins, aes(x = species, y = body_mass)) +
  geom_bar(position = "dodge") +
  opts(legend.position = "top")
1
opts? What are opts?
Error in `opts()`:
! could not find function "opts"

ggplot2 News June 2012

ggplot2 0.9.2

----------------------------------------------------------------

THEME SYSTEM

* The `opts()` function has been renamed to `theme()`.

Solutions

Figure 1

Solution 0: name packages used

values were analysed in R (R Core Team, 2017) using the qqman package (Turner, 2014).

Citing R

# Citation for R
citation()
To cite R in publications use:

  R Core Team (2026). _R: A Language and Environment for Statistical
  Computing_. R Foundation for Statistical Computing, Vienna, Austria.
  doi:10.32614/R.manuals <https://doi.org/10.32614/R.manuals>.
  <https://www.R-project.org/>.

A BibTeX entry for LaTeX users is

  @Manual{,
    title = {R: A Language and Environment for Statistical Computing},
    author = {{R Core Team}},
    organization = {R Foundation for Statistical Computing},
    address = {Vienna, Austria},
    year = {2026},
    doi = {10.32614/R.manuals},
    url = {https://www.R-project.org/},
  }

We have invested a lot of time and effort in creating R, please cite it
when using it for data analysis. See also 'citation("pkgname")' for
citing R packages.

Citing R packages

# Citation for an R package
citation("lme4")
To cite lme4 in publications use:

  Douglas Bates, Martin Maechler, Ben Bolker, Steve Walker (2015).
  Fitting Linear Mixed-Effects Models Using lme4. Journal of
  Statistical Software, 67(1), 1-48. doi:10.18637/jss.v067.i01.

A BibTeX entry for LaTeX users is

  @Article{,
    title = {Fitting Linear Mixed-Effects Models Using {lme4}},
    author = {Douglas Bates and Martin M{\"a}chler and Ben Bolker and Steve Walker},
    journal = {Journal of Statistical Software},
    year = {2015},
    volume = {67},
    number = {1},
    pages = {1--48},
    doi = {10.18637/jss.v067.i01},
  }

Solution 1: name & version of packages

Numerical analyses were carried out using R v. 2.15.3 (R Core Team 2013) using the vegan package v. 2.0-9 (Oksanen et al. 2013).

Which packages to cite?

Potentially hundreds of packages used directly and indirectly.

Finding package versions

Numerical analyses were carried out using R v. `{r} getRversion()`
(R Core Team 2013) using the vegan package v.`{r} packageVersion("vegan")`
(Oksanen et al. 2013).

Using pakret package

Numerical analyses were carried out using `{r} pkrt("R")`
using `{r} pkrt("vegan")`.

Numerical analyses were carried out using R version 4.6.1 [@base] using the ‘vegan’ package version 2.7.5 [@vegan].

Solution 2: renv for reproducible R environment

  • detect which packages you use and their dependencies

  • keeps a lockfile - a list of the version of ALL the packages installed

  • makes a project library

  • will install correct version of packages in the lockfile when you start using a project

Demo renv

  1. Make a new rstudio project.
  2. Run renv::init()
  3. Add an R script file with some library() calls
  4. Install packages with renv::install() (both CRAN and GitHub)
  5. Run renv::status()
  6. Run renv::snapshot() to save changes or renv::restore() to revert
  7. Repeat 3–6

Using someone else’s project with renv

  1. Clone the repo
  2. Open in RStudio
  3. use renv::restore() to install packages

Pitfalls

  • renv only valid for the version of R it was built on
  • not all package can be discovered
    • finds library(dplyr), tidyr::nest(...) and dependencies
tar_option_set(packages = c("tidyverse"))
  • solution use targets::tar_renv()

  • solution use R file with library() calls

  • Don’t forget to renv::update() packages to get bugfixes.

renv limitations

renv makes the list of packages available.

Does nothing for the all the external dependencies.

You want to reproduce a paper using R 3.6.3 …

Solution 3: Containers

Virtual machines vs containers

Containers

  • docker

  • podman

  • singularity/apptainer

Use for reproducibility, production, high-performance computers

Install podman

Download and install podman from https://podman.io/

Test it is working:

Terminal
podman run quay.io/podman/hello

Docker images

Docker images are snapshots of a computer system

Can be downloaded and used

Images can be stacked

Images have version control

Rocker - R images for Podman

---
config:
  flowchart:
    padding: 10
---

flowchart BT
  ubuntu([ubuntu---])
  rver([rocker/r-ver-----])
  rstudio([rocker/rstudio------])
  tidyverse([rocker/tidyverse------])
  verse([rocker/verse-----])
  geospatial([rocker/geospatial------])
  geospatial-->verse-->tidyverse-->rstudio-->rver-->ubuntu

Terminal
podman run --rm -ti -e PASSWORD=pass \
  -p 8787:8787 docker.io/rocker/rstudio:4.5.3

--rm remove image after use
-ti interactive
-e environmental variables
-p port
docker.io registry
rocker/rstudio:4.5.3 image & version tag

Open browser http://localhost:8787
Usename: root
Password: pass (or whatever you set)

Adding files

use -v option to mount files

Terminal
podman run --rm -ti -v .:/root -e PASSWORD=pass -p 8787:8787 \
  docker.io/rocker/rstudio

Files edited in container will be updated outside.

(Also possible to make files read-only)

Adding dependencies with renv

Make new image from a Dockerfile

Dockerfile
# set base image
FROM docker.io/rocker/tidyverse:4.5.3 
# install renv into image
RUN R -e "install.packages('renv', repos = c(CRAN = 'https://cloud.r-project.org'))"
# copy renv lock into project & restore
WORKDIR /root
COPY renv.lock renv.lock
RUN R -e "renv::restore()"

Build Dockerfile into image with

Terminal
podman build -t thesis_image .

Run the image with

Terminal
podman run -ti -v .:/root -p 8787:8787 thesis_image

Podman compose

Command line is too complex to want to write every time.

compose.yml
services:
  rstudio:
    image: "docker.io/rocker/rstudio:4.5.3"
    ports:
      - "8787:8787"
    volumes:
      - type: bind
        source: .
        target: /root
    working_dir: /root
    environment:
      - PASSWORD=yourpassword

Run with

Terminal
podman compose compose.yml up

# close session with
podman compose down

Podman desktop

Use for for starting, stopping and managing images.

Solution 4: Nix - package manager

Nix language downloads packages

R interface with rix package

  • simplifies creating Nix expressions, which define reproducible environments.
  • lets you work interactively in RStudio

Rix example

  1. install Nix

  2. Use rix to make Nix expression

library(rix)

rix(
  date = "2025-02-28", # set a date
  r_pkgs = c("dplyr", "ggplot2"), # List all the packages you need
  ide = "rstudio", # List whatever editor you need
  project_path = ".",
  overwrite = TRUE
)
  1. Build nix environment
Terminal
nix-build

Remaining problems

  • dependencies on external API (e.g. gbif, leaflet)