install.packages(c(
"renv", "tidyverse", "broom", "palmerpenguins", "quarto", "knitr"
))Welcome to the hands-on lab on Managing R environment with renv. In this lab you will practice using renv for package management.
Each section builds on the previous one. Complete the exercises in order. When you are stuck, expand the Hints or Solution blocks — but try on your own first!
1 Setup
Before starting, make sure the required packages are available:
Work in a new directory throughout this lab. All exercises should be done inside that project directory.
2 Initialise renv
Initialise renv in your project and inspect what it creates.
renv::init()Remember to restart the R session after calling renv::init() to ensure the private library is used.
Questions:
- Which files and folders were created?
- What does the
.Rprofilefile contain, and why is it important? - Open
renv.lockin a text editor. What format is it? What information does it record?
After calling renv::init(), look at your project directory. You should see new files and folders. List them with list.files(all.files = TRUE) to include hidden files.
3 Install and Snapshot
Create a new R script test.r in your project with the following content:
library("palmerpenguins")- Check status of the project with
renv::status()
Install the palmerpenguins package.
renv::install("palmerpenguins")- Check status again with
renv::status()
Snapshot the project to update the lock file.
- Check status again with
renv::status()
Questions:
- What does
renv::status()report before and afterrenv::snapshot()? - Find the
palmerpenguinsentry inrenv.lock. What fields does it have? - How would a collaborator recreate this exact environment on their machine?
This may not look exactly the same for everyone depending on your local setup. If you already had palmerpenguins installed, the first renv::status() may not report it as missing.
# Check status before install
renv::status()
# The following package(s) are used in this project, but are not installed:
# - palmerpenguins
# Check status after install before snapshot
renv::status()
# The following package(s) are in an inconsistent state:
#
# package installed recorded used
# palmerpenguins y n y
renv::snapshot()
# Check status after snapshot
renv::status()
# → "No issues found -- the project is in a consistent state."
# Collaborator would run:
renv::restore()4 Simulate Restore
Simulate what happens when a collaborator clones your project.
- Note the current
renv.lockcontents. - Remove
palmerpenguinsfrom the library:
renv::remove("palmerpenguins")
renv::status()- Restore from the lock file:
renv::restore()- Confirm
palmerpenguinsis back andrenv::status()is clean.
renv::remove() removes a package from the private library but does not update the lock file. renv::restore() uses the lock file to reinstall everything that is missing.
5 Detect Dependencies
Create a script analysis.r in your project with the following content:
library(tidyverse)
library(palmerpenguins)
library(broom)
penguins_clean <- penguins |> tidyr::drop_na()
model <- lm(body_mass_g ~ flipper_length_mm + species, data = penguins_clean)
tidy(model)Then run:
renv::dependencies()Questions:
- Does
renvdetect all three packages (tidyverse,palmerpenguins,broom)? - What happens if you add
library(ggplot2)inside a function body? Doesrenvdetect it? - Snapshot again. Does the lock file change?
# renv::dependencies() scans project files such as .R, .Rmd, .qmd,
# .Rnw, and DESCRIPTION files, excluding ignored paths.
deps <- renv::dependencies()
print(deps)
# ggplot2 inside a function body is still detected because renv parses
# all R code, not just top-level statements.
renv::snapshot()
# If ggplot2 was already in the library (as a tidyverse dependency),
# it may already be in the lock file. If it was new, the lock file updates.6 Session
Click here
sessionInfo()R version 4.5.3 (2026-03-11)
Platform: x86_64-conda-linux-gnu
Running under: Ubuntu 26.04 LTS
Matrix products: default
BLAS/LAPACK: /home/roy/miniforge3/envs/r-4.5/lib/libopenblasp-r0.3.33.so; LAPACK version 3.12.0
locale:
[1] LC_CTYPE=en_US.UTF-8 LC_NUMERIC=C
[3] LC_TIME=en_US.UTF-8 LC_COLLATE=en_US.UTF-8
[5] LC_MONETARY=en_US.UTF-8 LC_MESSAGES=en_US.UTF-8
[7] LC_PAPER=en_US.UTF-8 LC_NAME=C
[9] LC_ADDRESS=C LC_TELEPHONE=C
[11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C
time zone: Europe/Stockholm
tzcode source: system (glibc)
attached base packages:
[1] stats graphics grDevices utils datasets methods base
loaded via a namespace (and not attached):
[1] htmlwidgets_1.6.4 compiler_4.5.3 fastmap_1.2.0 cli_3.6.6
[5] tools_4.5.3 htmltools_0.5.9 otel_0.2.0 yaml_2.3.12
[9] rmarkdown_2.31 knitr_1.51 jsonlite_2.0.0 xfun_0.59
[13] digest_0.6.39 rlang_1.3.0 evaluate_1.0.5