1

我宁愿有一个配置文件并在其中列出项目所需的包,而不是依靠renv::init()抓取项目并找到我需要的所有东西(它通常不能)。

所以我的问题是 - 我如何明确告诉 renv 项目需要哪些包,一个例子将不胜感激。

4

2 回答 2

1

这里有两种可能的前进方式:

  1. 配置renv为使用“显式”快照,如https://rstudio.github.io/renv/reference/snapshot.html#snapshot-type中所述- 此工作流程要求您在DESCRIPTION文件中列出您的包要求;

  2. 手动使用renv::init(bare = TRUE)+ renv::install(<packages>)(或您自己的包安装功能)安装项目所需的包,<packages>从您维护的某个单独源构建列表。

如果您有希望实现的特定工作流程,那么您可以考虑在https://github.com/rstudio/renv/issuesrenv提交功能请求。

于 2020-11-02T05:11:38.790 回答
1

这个renv包做了各种花哨的事情:从几个不同的位置安装,设置一个项目特定的库,以便你可以控制项目的版本,等等。如果你需要这些东西,我认为你不走运。据我所知,它无法传递依赖项列表,它需要扫描您的源代码以找到它们。我想你可以包括一个像

loadPackages <- function() {
  requireNamespace("foo")
  requireNamespace("bar")
   ...
}

为了更容易renv找到您所需的软件包,但如果它以其他方式失败(例如,您有不完整的文件无法正确解析),这将无济于事。

如果你不需要所有花哨的东西,你可以使用下面的函数:

needsPackages <- function(pkgs, install = TRUE, update = FALSE, 
              load = FALSE, attach = FALSE) {
  missing <- c()
  for (p in pkgs) {
    if (!nchar(system.file(package = p)))
      missing <- c(missing, p)
  }
  if (length(missing)) {
    missing <- unique(missing)
    if (any(install)) {
      toinstall <- intersect(missing, pkgs[install])
      install.packages(toinstall)
      for (p in missing)
        if (!nchar(system.file(package = p)))
          stop("Did not install: ", p)
    } else
      stop("Missing packages: ", paste(missing, collapse = ", "))
  }
  if (any(update))
    update.packages(oldPkgs = pkgs[update], ask = FALSE, checkBuilt = TRUE)
  for (p in pkgs[load])
    loadNamespace(p)
  for (p in pkgs[attach])
    library(p, character.only = TRUE)
}

这是我在一个项目中使用的。你称之为

needsPackages(c("foo", "bar"))

它会安装缺少的那些。它还可以更新、加载或附加它们。它只是使用标准功能install.packages从 CRAN 安装,没有花哨的安装位置选择,或特定软件包版本的维护。如果你确实使用了像这样简单的东西,你应该在sessionInfo()之后运行以记录包版本号,以防你以后需要返回到相同的状态。(虽然回到那个状态可能会很痛苦!)

于 2020-10-31T16:53:24.907 回答