2012-02-18 162 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) 
} 
相關問題