This article explains the internals of R dependency management in Rhino. Practical instructions for adding, removing and updating dependencies can be found in the documentation of rhino::pkg_install() and rhino::pkg_remove().

Rhino relies on {renv} to manage the R package dependencies of your project. With {renv} you can create an isolated package library for each application and easily restore it on a different machine using the exact same package versions. This is crucial for the maintainability of any project.

To learn more about {renv} visit its website. This article describes the specifics of how Rhino uses {renv} assuming some basic familiarity with the package.

Snapshot types

{renv} offers different snapshot types. By default it performs an implicit snapshot: it tries to detect the dependencies of your project by scanning your R sources. While convenient in small projects, this approach lacks fine control and can be inefficient in larger code bases.

It would be preferable to use explicit snapshots: the dependencies of your project must be listed in a DESCRIPTION file. Unfortunately we faced some issues with this snapshot type in deployments. Instead, Rhino uses the following setup:

  1. Implicit snapshot (configured in renv/settings.dcf).
  2. A dependencies.R file with dependencies listed explicitly as library() calls.
  3. A .renvignore file which tells {renv} to only read dependencies.R.

This solution offers us the benefits of explicit snapshots (fine control, efficiency) and works well in deployment.

Manual dependency management

In most cases the only functions you will need are rhino::pkg_install() and rhino::pkg_remove(). However it is still possible to manage dependencies using the underlying {renv} functions directly. This can be helpful in some unusual situations (e.g. broken lockfile, installing a specific package version).

{renv} will only save to the lockfile the packages which are installed in the local library, and it will remove the packages which are not installed. Thus you should always run renv::restore(clean = TRUE) before performing the steps below.

Add a dependency

  1. Add a library(package) line to dependencies.R.
  2. Call renv::install("package").
  3. Call renv::snapshot().

Update a dependency

  1. Call renv::update("package").
  2. Call renv::snapshot().

Calling renv::install("package") instead of renv::update("package") will have the same effect.

Remove a dependency

  1. Remove the library(package) line from dependencies.R.
  2. Call renv::snapshot().
  3. Call renv::restore(clean = TRUE).

It is not recommended to use the renv::remove() function, as it will remove a package from the local library even if it is still required by other packages. For example, renv::remove("glue") followed by renv::snapshot() will leave you without the {glue} package in your lockfile, even though it is required by {shiny}.



Appsilon/rhino documentation built on Sept. 27, 2024, 7:01 p.m.