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

时间:2012-02-18 13:35:34

标签: r packages

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

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

如何首先检查软件包是否已安装,然后仅针对那些软件包运行install.packages()

16 个答案:

答案 0 :(得分:135)

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

答案 1 :(得分:46)

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

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调用中输入。

答案 2 :(得分:43)

如果你想尽可能简单地做到这一点:

packages <- c("ggplot2", "dplyr", "Hmisc", "lme4", "arm", "lattice", "lavaan")
if (length(setdiff(packages, rownames(installed.packages()))) > 0) {
  install.packages(setdiff(packages, rownames(installed.packages())))  
}

将第一行中列出的软件包替换为运行代码所需的软件包,并发表声明!

答案 3 :(得分:14)

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

答案 4 :(得分:9)

# 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")
  }

答案 5 :(得分:8)

我建议使用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

答案 6 :(得分:7)

requiredPackages = c('plyr','ggplot2','ggtern')
for(p in requiredPackages){
  if(!require(p,character.only = TRUE)) install.packages(p)
  library(p,character.only = TRUE)
}

答案 7 :(得分:6)

我找到了一个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

答案 8 :(得分:4)

我使用的解决方案来自Sacha Epskamp和Shuguang的输入。这是功能:

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

它可以无声地工作,如果已安装软件包“pacote”,则不回显任何内容,否则安装它。不要忘记在引号之间写下包的名称!

答案 9 :(得分:4)

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{\link{require}}
#' @param quietly See \code{\link{require}}
#' @param warn.conflicts See \code{\link{require}}
#' @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 \code{Warning 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

答案 10 :(得分:4)

我已经实现了以静默方式安装和加载所需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);

答案 11 :(得分:2)

试试这个怎么样?

#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")}

答案 12 :(得分:1)

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

编辑:dang,Ninja'd一分钟!

编辑:一般建议:加载包sos,您会发现很容易得到很多“有没有XXXXX功能的问题”的答案。

答案 13 :(得分:0)

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

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

答案 14 :(得分:0)

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

## 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)

答案 15 :(得分:0)

看看我的旧功能,使用上面的提示更新它,这就是我得到的。

# 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.