web-dev-qa-db-ja.com

install.packages()を実行する前にインストール済みパッケージを確認してください

異なるコンピューター上の複数のユーザーと共有されるRスクリプトがあります。その行の1つにinstall.packages("xtable")コマンドが含まれています。

問題は、誰かがスクリプトを実行するたびに、Rは明らかにパッケージの再インストールにかなりの時間を費やすことです(実際のケースには複数のパッケージのベクトルがあるため、実際には時間がかかります)。

パッケージがインストールされているかどうかを最初に確認し、インストールされていないパッケージに対してのみinstall.packages()を実行するにはどうすればよいですか?

119
Waldir Leoncio

試行:require("xtable")または"xtable" %in% rownames(installed.packages())

136
Shuguang

これは、パッケージをチェックし、そうでない場合はインストールしてから再度ロードするためによく使用する関数です。

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呼び出しで入力できます。

47
Sacha Epskamp

できるだけ簡単にしたい場合:

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

最初の行にリストされているパッケージを、コードの実行に必要なパッケージに置き換えてください。

44
Sean Murphy

また、CRANパッケージ pacman があります。これには、1つ以上のパッケージをインストールし(必要な場合のみ)、それらをロードするp_load関数があります。

14
Nick Kennedy
# 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")
  }
9
Duc Tran

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

ライブラリをロードするために常にすべてのスクリプトに入れた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
6
CousinCocaine

私が使用したソリューションは、Sacha EpskampとShuguangの入力から派生したものです。関数は次のとおりです。

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

パッケージ「pacote」がすでにインストールされている場合は何もエコーせず、それ以外の場合はインストールします。引用符の間にパッケージの名前を書くことを忘れないでください!

4
Waldir Leoncio

必要な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);
4
Pratik Patil

またはgithub、glibraryのdrknexus/repsychからの大げさな例 。ほぼ確実にこれを行うためのより効率的でより良い方法がありますが、私はそれを長い間プログラムしましたが、基本的には機能します。

  • 既定のクラウドオプションが利用可能であれば、レポが選択されていない場合でも機能します。古いバージョンの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
4
russellpierce

これを試してみてはいかがですか?

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

スクリプトから行を削除しないのはなぜですか?エンドユーザーが必要に応じてxtableをインストールするスマートを持っていない場合、より大きな問題が発生します:-(。つまり、installed.packages()をチェックしてください

編集:ダン、1分で忍者!

編集:一般的な提案:パッケージsosをロードすると、「XXXXXを実行する関数はありますか?」という質問に対する答えを簡単に得ることができます。

1
Carl Witthoft

これでうまくいくはずです。複数を確認する必要がある場合は、required.packagesをベクトルにすることができます。

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

皆の反応を読んで、私はあちこちでいくつかのヒントを取り、私のものを作成しました。実際にはほとんどに非常に似ています。

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

私の古い機能を見て、上記のヒントを使用してそれを更新し、これは私が得たものです。

# 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
Dom Grey