R中的依赖管理

16
R是否有依赖管理工具来方便地处理项目特定的依赖关系?我正在寻找类似于Java的Maven、Ruby的Bundler、Python的Virtualenv、Node的NPM等工具。
我知道DESCRIPTION文件中的“Depends”子句以及R_LIBS工具,但这些似乎不能共同提供解决一些常见工作流的解决方案。
我希望能够检出一个项目并运行一个单独的命令来构建和测试该项目。该命令应将所需的任何软件包安装到项目特定的库中,而不会影响全局的R安装。例如:
my_project/.Rlibs/*

请查看 R 包 ProjectTemplatedevtools - Ramnath
ProjectTemplate不支持此功能。文档中指出,必须先安装库:“libraries:这是用户想要在调用load.project()时自动加载的所有R软件包的逗号分隔列表。在调用load.project()之前,必须已经安装这些软件包。默认情况下,此列表包括reshape、plyr、ggplot2、stringr和lubridate软件包。” - yoni
1
看起来开发工具有一些很棒的东西,但在某些方面也存在不足。 - yoni
2
我认为你想要的在R语言中是完全可行的,但目前还没有人做过。 - hadley
1
如果您想要一个开发工具的解决方案,dev_mode(); install_deps("path/to/package"); check() 是非常接近的。 - hadley
我的同事发现了这篇由Jeroen Ooms撰写的关于R语言依赖和版本管理现状的精彩总结:http://arxiv.org/abs/1303.2140 - yoni
4个回答

7

packrat 软件包的作用是:

将所需的软件包安装到项目特定的库中,而不会影响全局 R 安装。

它允许在不同的项目本地软件包库中安装相同软件包的不同版本。

即使这个问题已经五年了,但我还是想添加这个答案,因为在问题被问出来时,这个解决方案显然还不存在(据我所知,packrat 2014年首次在 CRAN 上出现)。

更新(2019年11月)

新的 R 软件包 renv 取代了 packrat


谢谢Guillaume。请看我对已接受答案中类似评论的回复。事情很可能已经改变,所以请随意发表评论。 - yoni
谢谢,我在发布之前错过了上面的评论。但我想回答中提供packrat的可见性是相关的(很容易忽略评论)。 - Guillaume
同意。谢谢,Guillaume。 :) - yoni

7
很不幸,你只能在DESCRIPTION:文件中找到Depends:,原因如下:
  • R本身是相当跨平台的,但这意味着我们需要在各个平台和操作系统上工作
  • 除了 R 包之外的编码依赖项需要以便携式方式在操作系统中进行编码 - 很难对像“PNG 图形库”这样的简单内容进行编码,以便可以在系统之间无歧义地解析
  • Windows 没有软件包管理器
  • 据我所知,OS X 没有将 Apple 提供的和其他开源项目提供的混合起来的软件包管理器
  • 即使在 Linux 发行版中,您也无法获得一致性:以 RStudio 为例,它有两个软件包(所有软件包都提供其依赖项!)适用于 RedHat / Fedora 和 Debian / Ubuntu

这是一个难题。


5
作为一个临时措施,我编写了一个新的rbundler包。它将项目依赖项安装到项目特定的子目录中(例如<PROJECT>/.Rbundle),使用户可以避免使用全局库。 我们在Opower已经使用rbundler几个月了,并且看到了开发人员工作流程、可测试性和内部软件包的可维护性方面的巨大改进。结合我们的内部软件包存储库,我们已经能够稳定地开发十多个用于生产应用程序的软件包。
常见的工作流程:
  • 从github检出项目
  • 进入项目目录
  • 启动R
  • 从R控制台:

    library(rbundler)

    bundle('.')

所有依赖项将被安装到./.Rbundle中,并创建一个.Renviron文件,其内容如下:

R_LIBS_USER='.Rbundle'

任何在该项目目录中运行的 R 操作都将遵循项目特定的库和包依赖关系。请注意,虽然此方法使用 package DESCRIPTION 来定义依赖关系,但它不需要实际的包结构。因此,rbundler 成为了管理 R 项目的通用工具,无论是简单的脚本还是完整的软件包。

2
乍一看,这似乎与RStudio团队最近发布的PackRat(http://rstudio.github.io/packrat/)非常相似。我错了吗? - Eike P.
4
感谢你提出这个问题,@jhin。在我开始开发rbundler的时候,我与@hadley和RStudio的团队讨论过这个问题。两者之间的区别在于,rbundler专注于_包_的开发,并利用了您DESCRIPTION文件中显式声明的依赖关系,而PackRat则专注于一般项目的开发,并通过反射来推导你的依赖关系。PackRat有一些额外的功能,可以快照您的依赖关系,以方便部署和共享。我相信这是他们作为管理托管项目的解决方案的首要任务。 - yoni
啊,我明白了。我只是试图理解使用rbundler进行软件包部署工作流程,但我不太确定是否正确。假设我已经开发了一个软件包,并使用rbundler捆绑了它的依赖项。当有人安装我的软件包时,例如使用devtools的'install("mypack")'从miniCRAN(假设这是您所说的“我们的内部软件包存储库”)安装时会发生什么?如何解决软件包依赖关系? - Eike P.
旁边的问题:rbundler如何存储软件包?我知道PackRat主要以源代码形式存储软件包,以便使依赖项可在不同平台上移植。rbundler是如何解决这个问题的?(也许您想在项目的GitHub / CRAN页面上包含此信息?至少我在那里找不到任何答案。) - Eike P.
rbundler 并不对软件包进行任何高级操作,它只是管理特定项目的 library,并将软件包安装到其中。正如此处的答案所提到的那样,该库是通过覆盖 R 的标准 R_LIBS_USER 进行配置的。也许我应该在 README 中链接到 R 的库管理配置。 - yoni

1
您可以使用以下工作流程:
1)创建一个脚本文件,其中包含您想要设置的所有内容,并将其存储在项目目录中,例如projectInit.R。
2)从您的.Rprofile(或任何其他在启动时由R执行的文件)中使用try语句来源化此脚本。
try(source("./projectInit.R"), silent=TRUE)

这将确保即使没有找到projectInit.R文件,R也能正常启动而不会出现错误信息

3)如果您在项目目录中启动R,并且该目录中存在projectInit.R文件,则该文件将被调用并准备就绪

这是从Linux的角度来看的,但在Windows和Mac下也应该以同样的方式工作。


抱歉 - 我没有看到“安装”部分。我必须跟随Dirk的意见 - 这将必须针对特定平台,但是例如bash脚本会很方便,可以与上述projectInit.R文件的源代码一起实现可能需要的所有功能。 - Rainer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接