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

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

问题是每次有人运行脚本时,R花费大量的时间显然重新安装包(实际上它需要一些时间,因为真正的情况下有几个包的向量)。

我怎样才能首先检查包是否安装,然后只运行install.packages()为不是?

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

这是我经常用来检查一个包的function,否则安装它并重新加载:

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

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

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

将第一行列出的软件包replace为运行你的代码所需的软件包,然后瞧!

还有CRAN软件包pacman具有p_loadfunction来安装一个或多个软件包(但只有在必要的时候),然后加载它们。

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

我发现一个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 

或者github上的drknexus/repsych ,glibrary的一个大举的例子 。 几乎肯定有更高效和更好的方法来做到这一点,但我编程了很久,它基本上工作。

  • 即使没有通过采用默认云选项(如果可用)select回购,它也能正常工作。 如果您使用的是较旧版本的R,则会回滚并根据国家/地区代码select镜像。
  • 它试图加载库(这一步可以使用上面的一些方法更高效)
    • 如果失败,它会尝试安装它
    • 如果安装失败,它会通知你哪些软件包安装失败
  • 这是正确的,包,多个包可以加载/安装在一个单一的传递与他们的依赖(至less通常,这里可能有一个错误)。

例如: glibrary(xtable,sos,data.table)但是如果你调用glibrary("xtable","sos","data.table")我不认为它会吓倒。 推/拉/叉欢迎。

代码function:

 #' 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", eg 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 

我使用的解决scheme来源于Sacha Epskamp和曙光的投入。 这个function:

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

它静静地工作,如果包装“pacote”已经安装,否则什么都不回声。 不要忘记在引号之间写下包裹的名字!

我已经实现了安装和加载所需的R软件包的function。 希望可能有帮助。 这里是代码:

 # 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); 
 requiredPackages = c('plyr','ggplot2','ggtern') for(p in requiredPackages){ if(!require(p,character.only = TRUE)) install.packages(p) library(p,character.only = TRUE) } 

试试这个怎么样?

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

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

编辑:dang,忍者一分钟!

编辑:一般的build议:加载软件包sos ,你会发现很容易得到很多的答案“是否有一个function,做XXXXX”的问题。

我build议使用system.file更轻量级的解决scheme。

 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 

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

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

读了大家的回答,我在这里和那里提了一些提示,并创build了我的。 其实非常相似。

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

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

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