How to write an Rstudio template that uses renv

I'd like to write an RProject template for some analyses I do regularly. I'm following some guides here. Because I typically use renv in these analyses, I'd like to add an option to use renv upon setup. However, when I do setup projects with my template, renv doesn't appear to work.

Here is my setup function

statistical_analysis_template <- function(path, ...) {

  dots <- list(...)
  # ensure path exists
  dir.create(path, recursive = TRUE, showWarnings = FALSE)

  if(dots$use_renv) {

    # If using renv, there are some packages I will very likely need
    packages <- c('dplyr')

    renv::init(project=path, bare=T, force=F, load = F, restart = F)
    renv::install(packages = packages, project=path, prompt = FALSE)
  }

}

and here is my dcf file

Binding: statistical_analysis_template
Title: Statistical Analysis Template

Parameter: use_renv
Widget: CheckboxInput
Label: Use Renv
Default: On
Position: left

When I load my library and use the template from the GUI, I can successfully create a new project with the template. I can see the renv/ directory and lock file in the project directory. I can activate the renv using renv::activate.

But dplyr is not installed. When I search for documentation for dplyr::select I am returned

 ?dplyr::select
Error in find.package(if (is.null(package)) loadedNamespaces() else package,  : 
  there is no package called ‘dplyr’

I don't think the project argument is working as you expected. Even though you specify project=path, since renv is not activated, it doesn't write to the local project directory.

Here is a reprex that shows that {dplyr} is not installed in the local renv project directory when using the project argument.

x <- tempfile()
dir.create(x)
setwd(x)
renv::init(project=getwd(), bare=T, force=F, load = F, restart = F)
renv::install(packages = "dplyr", project=getwd(), prompt = FALSE)
dir(Sys.glob("renv/library/R-*/*/"))
## [1] "renv"

I agree this is surprising behavior. I don't know enough about {renv} to know if this is a bug or the expected behavior. I skimmed the source code, and project is passed to the installation functions, so I'm not sure what the issue is.

Also I don't recommend using ... here to stand in for use_renv. It's a required argument in your function code. The most transparent option would be to add it as an explicit argument, but at minimum you'd need to define it in the body of the function prior to checking its value in the if() statement

x <- tempfile()
statistical_analysis_template(x)
## Error in if (dots$use_renv) { : argument is of length zero

The problem here is that renv::init(bare = TRUE) does not set the library paths for the session. For example:

> renv::init(bare = TRUE)
- renv activated -- please restart the R session.
> .libPaths()
[1] "/Users/kevin/Library/R/arm64/4.3/library"
[2] "/Library/Frameworks/R.framework/Versions/4.3-arm64/Resources/library"

Note that the issue would be resolved if you do restart R as renv suggests. Alternatively, you could invoke renv in an R sub-process, to ensure that renv is appropriately loading after initialization in that sub-process.

1 Like