Reproducible workflows in R

Testing, debugging, profiling, renv, targets, packaging and Git for ecologists: the habits that keep an R analysis correct and still runnable years later.

An ecological analysis is usually written once, under time pressure, by somebody who is not a software engineer and does not want to become one. It then has to survive review, a revision eighteen months later, a new laptop, a package update, and a colleague who wants to run it. Most of the advice aimed at that situation is a list of tools. These tutorials are not that. They ask a narrower question about each habit: what class of error does it actually catch, and what does it cost you.

The answers are measured rather than asserted. Every tutorial builds the tool by hand in base R before naming the package that does it properly, plants known bugs or a known drift, and scores what the habit recovers. That order matters, because a lockfile, a pipeline and a test suite all give the same comfortable feeling, and they protect against completely different failures. Knowing which one is protecting you is the difference between a reproducible project and a project with reproducibility decorations on it.

Writing code that is worth trusting

The expensive errors are not the ones that stop the script. They are the ones that run to the end and hand back a plausible wrong number, which then goes into a figure and a sentence.

  • Testing your analysis code puts a test runner in a screenful of base R and then earns its keep the hard way, against a pile of deliberately planted bugs, sorting the kinds of test that catch things from the kinds that only look diligent.
  • Debugging and defensive R code works through the failures that R makes silently and cheerfully: silent recycling, the factor that arrives as an integer, the missing value that propagates without complaint, and where a hard stop beats a handler.
  • Speeding up your analysis code insists on measuring before rewriting, separates the speedup that stays constant as the data grows from the one that keeps growing, and makes the case for leaving slow readable code alone.
  • Checking an analysis script is the audit the other three lead to: does the script run from a clean session, does it give the same answer twice, and does it report the numbers it actually computed rather than the ones that were true last week.

Making the result survive the machine it was made on

Correct today on this laptop is not the standard. The standard is correct on somebody else’s machine, after the packages have moved on.

  • Pinning package versions with renv treats a lockfile as a claim and then tests the claim, including a changed default that alters the result with no error and no warning anywhere, and is honest about the part of the environment a lockfile does not record.
  • Building an analysis pipeline with targets reframes a pipeline as an invalidation graph rather than a list of scripts, and shows what happens when that graph is tracked in your head instead: cheaper, and wrong in a direction you will not notice.
  • Turning your code into an R package follows one helper function copied into several analyses and measures how far the copies drift apart, including the ones nobody edited.
  • Git for ecologists starts from the question a referee actually asks, which is which state of the code produced the figure in the manuscript, and works backwards to the smallest set of habits that can answer it.

What these tutorials assume

Base R throughout, with one plotting package. The test runner, the dependency graph, the profiling and the drift comparison are all written out rather than called from a package, because the point is to see what the tool is doing on your behalf and where its guarantee stops. The real packages are named where they belong, and the tutorials say plainly which of them you can skip and which you will regret skipping. Nothing here requires a server, a container or a continuous integration service.

Where this connects

Reproducibility is not a separate subject from analysis. It is the part of analysis that decides whether the rest of it can be believed twice.

  • R for ecologists is the layer underneath: getting field data into R, cleaning it and reshaping it, which is where most of the irreproducible steps are quietly performed by hand.
  • A reproducible statistical workflow is the short version of this whole page, written as a set of project conventions rather than as measurements.
  • Setting up R for ecology covers the project layout and the working directory habits that everything above assumes are already in place.
  • Data leakage in model validation is what a reproducibility failure looks like when it has teeth: code that runs, validates cleanly and reports a score it has not earned.

Newsletter

Get new tutorials by email

New R and QGIS tutorials for ecologists, straight to your inbox. No spam; unsubscribe anytime.

By subscribing you agree to receive these emails and confirm your address once. See the privacy policy.