2012-02-18 107 views
102

我有一个R脚本与不同计算机上的多个用户共享。其中一行包含install.packages("xtable")命令。在运行install.packages()前检查已安装的软件包()

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

如何首先检查软件包是否已安装,然后只运行install.packages()而不是?

+5

使用'require'(例如@ SachaEpskamp的解决方案)是要走的路。使用'rownames(installed.packages())'的方法很慢并且不总是可靠的(参见'find.package'的细节和'installed.packages'的提示)。 'require'确保软件包不仅可以安装,而且可以使用(即满足依赖关系等)。 – jbaums 2014-06-04 02:22:32

回答

116

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

+28

等'if(“xtable”%in%rownames(installed.packages())== FALSE){install.packages(“xtable”)}' – Henry 2012-02-18 14:02:23

+6

我用'if(!pacote%in%installed .packages())install.packages(pacote)'。这很好,很优雅,谢谢! – 2012-02-19 14:40:11

+0

InsPack < - function(pack){ if(!pack%in%installed。包()){ 打印 (粘贴( “安装”,包)) install.packages(包) } 其他打印(粘贴(包 “已安装”)) } – Faridcher 2015-09-08 18:25:42

1

为什么不直接从脚本中删除该行?如果最终用户不具有的智慧安装xtable根据需要,你有更大的问题:-( 这就是说,看看installed.packages()

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

编辑:一般建议:加载包sos,你会发现它很容易得到答案了不少“有,做XXXXX功能”的问题

+1

好吧,谁是weisenheimer通过3岁的帖子抨击只是为了downvote的东西? – 2015-04-30 12:24:47

39

这是一个函数I经典EN用于检查一个包,否则安装它,然后重新装入:

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

+1

或者选择在回购install.packages调用例如'install.packages(x,dep = TRUErepos ='http:// star-www.st-andrews.ac.uk/cran /'') – moadeep 2013-03-01 10:36:56

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

我使用萨沙Epskamp和曙光的输入得到的溶液。这里的功能:

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

它的工作原理默默地,呼应咱这包“包中”已经安装否则安装。不要忘记在引号之间写下包裹的名字!

+0

如果我为'else添加库(x) '在你的'if'函数中出现错误。有什么建议么? – 2015-03-25 14:57:35

+0

@ timothy.s.lau:你得到什么错误?你的条件写得如何? – 2015-03-25 18:31:36

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") 
    } 
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")} 
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"]] == "@[email protected]") { 
     #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 
+0

链接已损坏。这正是为什么StackOverflow不允许链接唯一的答案... – 2015-10-06 06:17:22

+1

@MilesErickson我没有想到任何人会希望在帖子中的这么多的代码。和许多代码只回答得到不赞成R随着包提前,所以链接到一个github存储库(仍然存在)对我来说是有道理的。无论如何,链接固定和代码添加。 – russellpierce 2015-10-06 06:23:09

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

如果你想简单地做越好:

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

替换那些需要在第一行列出的软件包来运行你的代码,瞧!

+0

我喜欢这种方法。当'packages'中的所有软件包已经安装时,这是一种耻辱。 – jbaums 2014-06-04 02:00:34

+1

不错,我已经更新了代码以避免这种情况,尽管我不想失去双线方法的简单性。也许别人可以想到一个更清洁的解决方案。 – 2014-06-04 02:04:03

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. 
+0

似乎没有为我工作和安装。文件似乎并不存在 – Dason 2015-03-28 13:28:24

+0

你可以提供一些更多的细节? – 2015-04-25 14:35:37

+0

因为它不起作用。 install.Files不是一个存在的函数。你在哪里从 – Dason 2015-04-25 14:57:10

3

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

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

1

我建议使用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 
4
requiredPackages = c('plyr','ggplot2','ggtern') 
for(p in requiredPackages){ 
    if(!require(p,character.only = TRUE)) install.packages(p) 
    library(p,character.only = TRUE) 
} 
相关问题