最近我似乎和合作者分享了很多代码。他们中的许多人是新手/中级R用户,并没有意识到他们必须安装他们还没有的包。

是否有一种优雅的方式来调用installed.packages(),比较那些我正在加载和安装如果丢失?


当前回答

有一个新的包(我是一个联合开发人员),Require,它是可复制工作流的一部分,这意味着函数在第一次运行或后续运行时产生相同的输出,也就是说,无论开始状态如何,最终状态都是相同的。下面安装任何缺失的包(我包含require = FALSE以严格解决最初的问题…通常我把这个设置为默认值,因为我通常希望它们加载到搜索路径)。

这两行位于我编写的每个脚本的顶部(根据需要调整包的选择),允许任何人在任何条件下(包括任何或所有依赖项缺失)使用脚本。

if (!require("Require")) install.packages("Require")
Require::Require(c("ggplot2", "Rcpp"), require = FALSE)

因此,您可以在脚本中使用它或将其传递给任何人。

其他回答

关于你的主要目标“安装他们还没有的库”。并且不管使用" installed .packages() "”。下面的函数掩码了require的原始函数。它尝试加载和检查命名包“x”,如果它没有安装,直接安装它,包括依赖项;最后正常加载。将函数名从'require'重命名为'library'以保持完整性。唯一的限制是包名应该加引号。

require <- function(x) { 
  if (!base::require(x, character.only = TRUE)) {
  install.packages(x, dep = TRUE) ; 
  base::require(x, character.only = TRUE)
  } 
}

所以你可以加载和安装包的旧时尚的方式R。 要求(“ggplot2”) 要求(“Rcpp”)

if (!require('ggplot2')) install.packages('ggplot2'); library('ggplot2')

“ggplot2”是包。它检查包是否安装,如果没有安装,就安装它。然后不管它采用哪个分支,它都会加载包。

在我的例子中,我想要一个可以从命令行(实际上是通过Makefile)运行的一行程序。下面是一个安装“VGAM”和“feather”的例子,如果它们还没有安装:

R -e 'for (p in c("VGAM", "feather")) if (!require(p, character.only=TRUE)) install.packages(p, repos="http://cran.us.r-project.org")'

在R内部,它就是:

for (p in c("VGAM", "feather")) if (!require(p, character.only=TRUE)) install.packages(p, repos="http://cran.us.r-project.org")

除了前面的解之外,这里没有别的解:

我只说一句 我硬编码回购参数(以避免任何弹出窗口询问使用的镜像) 我不想费心定义一个在其他地方使用的函数

还要注意重要的字符。only=TRUE(如果没有它,require将尝试加载包p)。

你可以使用require的返回值:

if(!require(somepackage)){
    install.packages("somepackage")
    library(somepackage)
}

我在安装后使用library,因为如果安装不成功或由于其他原因无法加载包,它将抛出异常。您可以使其更加健壮和可重用:

dynamic_require <- function(package){
  if(eval(parse(text=paste("require(",package,")")))) return(TRUE)
  
  install.packages(package)
  return(eval(parse(text=paste("require(",package,")"))))
}

此方法的缺点是必须以引号传递包名,而对于真正的require则不这样做。

source("https://bioconductor.org/biocLite.R")
if (!require("ggsci")) biocLite("ggsci")