在运行 install.packages() 之前检查已安装的软件包 [重复]

Posted

技术标签:

【中文标题】在运行 install.packages() 之前检查已安装的软件包 [重复]【英文标题】:Check for installed packages before running install.packages() [duplicate] 【发布时间】:2012-03-09 15:25:46 【问题描述】:

我有一个 R 脚本,它与不同计算机上的多个用户共享。其中一行包含install.packages("xtable") 命令。

问题在于,每次有人运行脚本时,R 显然会花费大量时间重新安装包(实际上确实需要一些时间,因为真实案例有多个包的向量)。

我怎样才能先检查软件包是否已安装,然后只为未安装的软件包运行install.packages()

【问题讨论】:

使用require(例如@SachaEpskamp 的解决方案)是可行的方法。使用rownames(installed.packages()) 的方法很慢并且并不总是可靠的(请参阅?find.package 的详细信息和?installed.packages 的注释)。 require 确保软件包不仅已安装而且能够使用(即满足依赖关系等)。 packageVersion("packageName") 【参考方案1】:

试试:require("xtable")"xtable" %in% rownames(installed.packages())

【讨论】:

等等if("xtable" %in% rownames(installed.packages()) == FALSE) install.packages("xtable") 我创建了一个带有if (!pacote %in% installed.packages()) install.packages(pacote) 的函数。这很好,够优雅,谢谢! InsPack 点赞packagename %in% rownames(installed.packages())require 的问题是,如果可能,它会自动加载包。有时这是不希望的。我同时使用包tidyverse(dplyr) 和signal - 都具有filter 的功能。由于我更频繁地使用dplyr::filter,因此我想要一种方法来检查signal 是否已安装但未加载。 installed.packages() 可能很慢【参考方案2】:

如果你想尽可能简单:

packages <- c("ggplot2", "dplyr", "Hmisc", "lme4", "arm", "lattice", "lavaan")

install.packages(setdiff(packages, rownames(installed.packages())))  

将第一行列出的包替换为运行代码所需的包,瞧!

注意:感谢 Artem 在下面的评论,已编辑以删除条件包装器。

【讨论】:

我喜欢这种方法。当packages 中的所有软件包都已安装时,这种行为令人遗憾。 很好——我已经更新了代码以避免这种情况,尽管我讨厌失去两行方法的简单性。也许其他人可以想到更清洁的解决方案。 在 R 3.6.2 中,您不需要 if 部分。只需install.packages(setdiff(packages, rownames(installed.packages()))) 就足够了。 (如果所有包都已安装,setdiff 将返回character(0),导致install.packages() 什么都不做。) 好消息 - 我将编辑回原来的、更简单的解决方案。谢谢!【参考方案3】:

这是我经常用来检查包的功能,否则安装它并再次加载:

pkgTest <- function(x)
  
    if (!require(x,character.only = TRUE))
    
      install.packages(x,dep=TRUE)
        if(!require(x,character.only = TRUE)) stop("Package not found")
    
  

pkgTest("xtable") 一样工作。它仅在设置了镜像时才有效,但您可以在 require 调用中输入它。

【讨论】:

或者在 install.packages 调用中选择一个 repo,例如 install.packages(x,dep=TRUErepos='http://star-www.st-andrews.ac.uk/cran/')【参考方案4】:

我建议使用system.file 的更轻量级的解决方案。

is_inst <- function(pkg) 
    nzchar(system.file(package = pkg))


is_inst2 <- function(pkg) 
    pkg %in% rownames(installed.packages())


library(microbenchmark)
microbenchmark(is_inst("aaa"), is_inst2("aaa"))
## Unit: microseconds
##            expr      min        lq       mean    median       uq       max neval
##  is_inst("aaa")   22.284   24.6335   42.84806   34.6815   47.566   252.568   100
## is_inst2("aaa") 1099.334 1220.5510 1778.57019 1401.5095 1829.973 17653.148   100
microbenchmark(is_inst("ggplot2"), is_inst2("ggplot2"))
## Unit: microseconds
##                expr      min       lq     mean   median       uq      max neval
##  is_inst("ggplot2")  336.845  386.660  459.243  431.710  483.474  867.637   100
## is_inst2("ggplot2") 1144.613 1276.847 1507.355 1410.054 1656.557 2747.508   100

【讨论】:

这样一个被低估的答案。 installed.packages() 慢得多。谢谢! not 在我的 linux 机器上工作(在我的 Windows 机器上工作正常)。两个可能的原因:(1) system.file 没有查看所有 .libPath() 位置,(2) 我基于 conda 的 R 安装以某种方式改变了 .libPaths。 你能不能尝试指定lib.loc 在后台,system.file 正在使用另一个 base 函数:find.package,这会更直接(注意:如果包不存在,需要 quiet=TRUE 以防止出现错误) 我对此进行了更多的扩展here,因为这个问题已经结束【参考方案5】:

还有 CRAN 包 pacman 具有 p_load 功能来安装一个或多个包(但仅在必要时)然后加载它们。

【讨论】:

【参考方案6】:
requiredPackages = c('plyr','ggplot2','ggtern')
for(p in requiredPackages)
  if(!require(p,character.only = TRUE)) install.packages(p)
  library(p,character.only = TRUE)

【讨论】:

【参考方案7】:
# Function to check whether package is installed
  is.installed <- function(mypkg)
    is.element(mypkg, installed.packages()[,1])
   

  # check if package "hydroGOF" is installed
  if (!is.installed("hydroGOF"))
    install.packages("hydroGOF")
  

【讨论】:

【参考方案8】:

我在某个地方找到了一个 packages 脚本,我总是将它放入每个脚本中以加载我的库。它将仅在需要时进行所有库处理(下载、安装和加载)。

# Install function for packages    
packages<-function(x)
  x<-as.character(match.call()[[2]])
  if (!require(x,character.only=TRUE))
    install.packages(pkgs=x,repos="http://cran.r-project.org")
    require(x,character.only=TRUE)
  

packages(ggplot2)
packages(reshape2)
packages(plyr)
# etc etc

【讨论】:

【参考方案9】:

我已经实现了静默安装和加载所需 R 包的功能。希望可能会有所帮助。代码如下:

# Function to Install and Load R Packages
Install_And_Load <- function(Required_Packages)

    Remaining_Packages <- Required_Packages[!(Required_Packages %in% installed.packages()[,"Package"])];

    if(length(Remaining_Packages)) 
    
        install.packages(Remaining_Packages);
    
    for(package_name in Required_Packages)
    
        library(package_name,character.only=TRUE,quietly=TRUE);
    


# Specify the list of required packages to be installed and load    
Required_Packages=c("ggplot2", "Rcpp");

# Call the Function
Install_And_Load(Required_Packages);

【讨论】:

我认为这确实是最直观的解决方案之一,尤其是如何获取Remaining_Packages这一行【参考方案10】:

我使用的解决方案来自 Sacha Epskamp 和曙光的意见。函数如下:

instalaPacotes <- function(pacote) 
  if (!pacote %in% installed.packages()) install.packages(pacote)

它静默工作,如果包“pacote”已经安装,则不回显,否则安装它。不要忘记在引号之间写下包的名称!

【讨论】:

如果我在 if 函数中为 else 添加库(x),我会收到错误消息。有什么建议吗? @timothy.s.lau:你遇到了什么错误?你的条件是怎么写的?【参考方案11】:

Or a massively overticked example from drknexus/repsych on github, glibrary。几乎可以肯定有更有效和更好的方法可以做到这一点,但我很久以前就对其进行了编程,它基本上可以工作。

即使未选择存储库也可以使用默认云选项(如果可用)。如果您使用的是旧版本的 R,它将回滚并根据国家/地区代码选择镜像。 它会尝试加载库(使用上述某些方法可以提高此步骤的效率) 如果失败,它会尝试安装它 如果安装失败,它将通知您哪些软件包安装失败 没错,包,多个包可以连同它们的依赖项一起加载/安装(至少通常情况下,这里可能存在错误)。

例如:glibrary(xtable,sos,data.table) 但我不认为如果你打电话给glibrary("xtable","sos","data.table") 会吓坏。欢迎推/拉/叉。

函数代码:

#' Try to load a library, if that fails, install it, then load it.
#'
#' glibrary short for (get)library.
#' The primary aim of this function is to make loading packages more transparent.  Given that we know we want to load a given package, actually fetching it is a formality.  glibrary skims past this formality to install the requested package.
#'
#' @export
#' @param ... comma seperated package names
#' @param lib.loc See \code\linkrequire
#' @param quietly See \code\linkrequire
#' @param warn.conflicts See \code\linkrequire
#' @param pickmirror If TRUE, glibrary allows the user to select the mirror, otherwise it auto-selects on the basis of the country code
#' @param countrycode This option is ignored and the first mirror with the substring "Cloud", e.g. the RStudio cloud, is selected.  If no mirrors with that substring are identified, glibrary compares this value to results from getCRANmirrors() to select a mirror in the specified country.
#' @return logical; TRUE if glibrary was a success, an error if a package failed to load
#' @note keep.source was an arguement to require that was deprecated in R 2.15
#' @note This warning \codeWarning in install.packages: InternetOpenUrl failed: 'The operation timed out' indicates that the randomly selected repository is not available.  Check your internet connection.  If your internet connection is fine, set pickmirror=TRUE and manually select an operational mirror.
#' @examples
#' #glibrary(lattice,MASS) #not run to prevent needless dependency
glibrary <- function(..., lib.loc = NULL, quietly = FALSE, warn.conflicts = TRUE, pickmirror = FALSE, countrycode = "us") 
  warningHandle <- function(w) 
    if (grepl("there is no package called",w$message,fixed=TRUE)) 
      return(FALSE) #not-loadable
     else 
      return(TRUE) #loadable
    
  

  character.only <- TRUE  #this value is locked to TRUE so that the function passes the character value to require and not the variable name thislib
  librarynames <- unlist(lapply(as.list(substitute(.(...)))[-1],as.character))
  #if package already loaded, remove it from librarynames before processing further
  si.res <- sessionInfo()
  cur.loaded <- c(si.res$basePkgs,names(si.res$otherPkgs)) #removed names(si.res$loadedOnly) because those are loaded, but not attached, so glibrary does need to handle them.
  librarynames <- librarynames[librarynames %!in% cur.loaded]
  success <- vector("logical", length(librarynames))
  if (length(success)==0) return(invisible(TRUE)) #everything already loaded, end.

  alreadyInstalled <- installed.packages()[,"Package"]
  needToInstall <- !librarynames %in% alreadyInstalled

  if (any(needToInstall)) 
    if (pickmirror) chooseCRANmirror()
    if (getOption("repos")[["CRAN"]] == "@CRAN@") 
      #Select the first "Cloud" if available
      m <- getCRANmirrors(all = FALSE, local.only = FALSE)
      URL <- m[grepl("Cloud",m$Name),"URL"][1] #get the first repos with "cloud" in the name
      if (is.na(URL))  #if we did not find the cloud,
        #Fall back and use the previous method
        message("\nIn repsych:glibrary:  Now randomly selecting a CRAN mirror. You may reselect your CRAN mirror with chooseCRANmirror().\n")
        #if there is no repository set pick a random one by country code
        getCRANmirrors.res <- getCRANmirrors()
        foundone <- FALSE  #have we found a CRAN mirror yet?
        #is it a valid country code?
        if (!countrycode %in% getCRANmirrors.res$CountryCode) 
          stop("In repsych::glibrary:  Invalid countrycode argument")
        
        ticker <- 0
        while (!foundone) 
          ticker <- ticker + 1
          URL <- getCRANmirrors.res$URL[sample(grep(countrycode, getCRANmirrors.res$CountryCode), 1)]
          host.list <- strsplit(URL, "/")
          host.clean <- unlist(lapply(host.list, FUN = function(x) return(x[3])))
          #make sure we can actually access the package list
          if (nrow(available.packages(contrib.url(URL)))!=0) foundone <- TRUE        
          if (ticker > 5) stop("In repsych::glibrary:  Unable to access valid repository.  Is the internet connection working?")
         #end while
       #end else
      repos <- getOption("repos")
      repos["CRAN"] <- gsub("/$", "", URL[1L])
      options(repos = repos)
     #done setting CRAN mirror
    #installing packages
    installResults <- sapply(librarynames[needToInstall],install.packages)
    #checking for successful install
    needToInstall <- !librarynames %in% installed.packages()[,"Package"]
    if (any(needToInstall)) 
      stop(paste("In repsych::glibrary: Could not download and/or install: ",paste(librarynames[needToInstall],collapse=", "),"... glibrary stopped.",sep=""))
     # done reporting any failure to install
   #done if any needed to install

  #message("In repsych::glibrary:  Attempting to load requested packages...\n")
  #success <- tryCatch(
  success <- sapply(librarynames,require, lib.loc = lib.loc, quietly = FALSE, warn.conflicts = warn.conflicts, character.only = TRUE)
  #, warning=warningHandle) #end tryCatch
  if(length(success) != length(librarynames)) stop("A package failed to return a success in glibrary.")


  if (all(success)) 
    #message("In repsych::glibrary:  Success!")
    return(invisible(TRUE))
   else 
    stop(paste("\nIn repsych::glibrary, unable to load: ", paste(librarynames[!success]), 
               collapse = " "))
  
  stop("A problem occured in glibrary") #shouldn't get this far down, all returns should be made.

NULL

【讨论】:

链接已损坏。这正是 *** 不允许仅链接答案的原因... @MilesErickson 我认为没有人会想要在帖子中包含这么多代码。随着包的推进,许多仅代码的答案在 R 中被弃用,因此链接到 github 存储库(仍然存在)对我来说很有意义。无论如何,链接已修复并添加了代码。【参考方案12】:

试试这个怎么样?

#will install the pROC library if you don't have it
if(!is.element('pROC', installed.packages()[,1]))
  install.packages('pROC')
else print("pROC library already installed")

【讨论】:

【参考方案13】:

为什么不直接从脚本中删除该行?如果最终用户没有根据需要安装 xtable 的聪明才智,那么您将遇到更大的问题 :-( 。 也就是说,请查看installed.packages()

编辑:该死,忍者一分钟!

编辑:一般建议:加载包 sos ,您会发现很容易得到很多“是否有执行 XXXXX 的函数”问题的答案。

【讨论】:

好的,谁是魏森海默通过 3 年前的帖子苦苦挣扎只是为了投反对票?【参考方案14】:

应该这样做。如果您需要检查多个向量,可以将required.packages 设为向量。

required.packages <- "data.table"
new.packages <- required.packages[!(required.packages %in% installed.packages()[,"Package"])]
if(length(new.packages)) install.packages(new.packages)

【讨论】:

【参考方案15】:

阅读了每个人的回复,我在这里和那里得到了一些提示并创建了我的。但实际上与大多数人非常相似。

## These codes are used for installing packages
# function for installing needed packages
installpkg <- function(x)
    if(x %in% rownames(installed.packages())==FALSE) 
        if(x %in% rownames(available.packages())==FALSE) 
            paste(x,"is not a valid package - please check again...")
         else 
            install.packages(x)           
        

     else 
        paste(x,"package already installed...")
    


# install necessary packages
required_packages  <- c("sqldf","car")
lapply(required_packages,installpkg)

【讨论】:

【参考方案16】:

查看了我的旧功能,使用上面的提示对其进行了更新,这就是我得到的。

# VERSION 1.0
assign("installP", function(pckgs)
    ins <- function(pckg, mc)
        add <- paste(c(" ", rep("-", mc+1-nchar(pckg)), " "), collapse = "");
        if( !require(pckg,character.only=TRUE) )
            reps <- c("http://lib.stat.cmu.edu/R/CRAN","http://cran.uk.R-project.org");
            for (r in reps) try(utils::install.packages(pckg, repos=r), silent=TRUE);
            if(!require(pckg,character.only = TRUE))   cat("Package: ",pckg,add,"not found.\n",sep="");
            else                                      cat("Package: ",pckg,add,"installed.\n",sep="");
        else                                          cat("Package: ",pckg,add,"is loaded.\n",sep="");  
    invisible(suppressMessages(suppressWarnings(lapply(pckgs,ins, mc=max(nchar(pckgs)))))); cat("\n"); 
, envir=as.environment("dg_base"))

installP(c("base","a","TFX"))
Package: base ------------------- is loaded.
Package: a ---------------------- not found.
Package: TFX -------------------- installed.

【讨论】:

似乎对我不起作用并安装。文件似乎不存在 你能提供更多细节吗? 因为它不起作用。 install.Files 不是一个存在的函数。你从哪里得到它 已编辑。我知道我从哪里得到 install.File... 另外,要创建“dg_base”附加(what=NULL,name="dg_base")。或者简单地删除分配并定义为正常功能。 我不会这样做。那是你的。我只是让你知道它不起作用。

以上是关于在运行 install.packages() 之前检查已安装的软件包 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

用于Mac的R错误消息的BiodiversityR包

R语言计算α多样性指数与画图

无法使用 install.packages 安装 R-forge 包

R软件安装程序包install.packages("TSA"),提示(因为‘lib’没有被指定),怎么解决,急求,谢谢!!!

R install.packages 返回“未能创建锁定目录”

Warning in install.packages : package ‘RGtk2’ is not available for this version of R