I realize this is an older question, but much of the technology in R has been greatly improved in recent months and years to address this exact issue. The generally accepted and modern approach for handling the sharing of code with package dependencies that may or may not be installed on a collaborator's computer or the target computer is to use the renv
package ("renv
" is short for "Reproducible Environment") which was first made available as renv
0.8.0
in late October of 2019. Version 1.0.0
was officially released on July 7, 2023, and, as of this post, the current CRAN release is Version 1.0.2
, which was made available last month on August 15, 2023.
This package greatly aids R collaborators in sharing code, packages (their exact version and their dependencies and their versions), and even the tracking of the exact version of R that was used to build and execute code in an R project.
To use it, typically the initial programmer creates an R project in R Studio/Posit and then initializes renv
within the project using the command renv::init()
. When this is executed, R does the following:
- Creates an project specific package library within the project, rather than using the general/global library or libraries (e.g.,
.libPaths()
). As part of this step, renv
also creates an renv
directory which contains some settings and files that most users don't generally bother with as renv
takes care of this for you.
- Creates an .
Rprofile
file, which is a project-specific R project profile that configures R to use the project specific library created in step 1 when you open the project.
- Creates a lockfile, called
renv.lock
in the project home directory, which logs details about all the packages and versions used by the project -- this is what makes using renv
the most attractive option for sharing code with package and package/version dependencies.
After initializing the project environment with the init()
command, the initial programmer develops and writes code as typical, installing packages in the usual manner (e.g., by simply entering install.packages("PackageName")
into the console) along they way as they are needed. These packages are stored into the project library, however, rather than any global library. When the initial programmer feels the code is in a satisfactory state to share the entire project, he simply issues the renv::snapshot()
command which simply updates the lockfile created in step 3 above, with the names, version numbers, etc. of all the packages used in the project.
At this point the initial programmer can share the project with other collaborators (ideally this is done through GitHub, Bitbucket, Azure DevOps, etc.). When any new collaborators open the R project, they simply enter the command renv::restore()
at the console. This will install the exact same version of every package used in the project (and it will be restored into the project library rather than the user's global package library).
This is an excellent workflow because it will ensure all users are working with the same version of the packages the initial developer used. Without renv
, it's possible that a collaborator has a totally different version of an R package installed in their global library, and it may function differently from the initial developer's package. This could result in the code breaking, or worse yet, running, but resulting in different output, possibly unbeknownst to the end users.
As perfectly described on the Introduction to renv vignette, renv
benefits users by ensuring package isolation, reproducibility across users and environments, and portability. renv()
also enjoys some other benefits like caching of R packages so that they don't have to be downloaded multiple times when used across projects. It also works with Python and Python packages. If you also want to ensure that every detail of an enviroment—including the operating system and other external (to R/R Studio) dependencies—are in place, you can easily do so too by combining renv
with a Docker image to fully containerize a solution!
One final note: if renv
seems similar to packrat
, that's because it is, somewhat. In fact the deverlopers of rev
first attempted to build a reproducible environment package using packrat
but gave up and "rolled their own" after struggling with its limitations. But it's vastly better too, I'd argue. The good news is, if you're already using packrat
and want to upgrade to this modern tool, you can easily do so with the renv::migrate()
command!
Good luck and happy collaborating!
R version 3.0.2 (2013-09-25) x86_64-w64-mingw32/x64 (64-bit)
.base
... ;-)