【问题标题】:Elegant way to check for missing packages and install them?检查丢失的软件包并安装它们的优雅方法?
【发布时间】:2011-05-04 15:51:10
【问题描述】:

这些天,我似乎与合著者分享了很多代码。他们中的许多人是 R 新手/中级用户,并没有意识到他们必须安装他们还没有的软件包。

有没有一种优雅的方式来调用installed.packages(),将其与我正在加载和安装的方式进行比较(如果丢失)?

【问题讨论】:

  • @krlmlr 接受的答案已过时并需要修改怎么办?它适用于R version 3.0.2 (2013-09-25) x86_64-w64-mingw32/x64 (64-bit) 下的我(用于一些快速测试)。
  • @BrianDiggs:至少已经出现了三个解决这个问题的包,下面只引用了一个。还有更多——这就是问题所在。
  • @krlmlr 使用包来确保(其他人)有必要的包似乎有点讽刺的鸡和蛋问题。但当然值得让了解他们的人写下答案。
  • @BrianDiggs:引导这个安装检查包是一个必要的麻烦,但很小。当然,除非该功能进入base... ;-)
  • 来自 Node.js,这太难了。这怎么不是语言的一流功能?

标签: r packages r-faq


【解决方案1】:

是的。如果您有软件包列表,请将其与 installed.packages()[,"Package"] 的输出进行比较并安装缺少的软件包。像这样的:

list.of.packages <- c("ggplot2", "Rcpp")
new.packages <- list.of.packages[!(list.of.packages %in% installed.packages()[,"Package"])]
if(length(new.packages)) install.packages(new.packages)

否则:

如果你把你的代码放在一个包中并使其成为依赖项,那么它们会在你安装包时自动安装。

【讨论】:

  • 我认为正确的语法是:if(length(new.packages)&gt;0) {install.packages(new.packages)}
  • @psql ,Shine 是对的,因为 ">0" 在 if 条件中是“隐含的”。运行它来验证它:new.packages &lt;- c(1,2)length(new.packages)if(length(new.packages)){print("hello!")}else{print("oh no!")}
  • installed.packages 的文档指出:“当安装了数千个包时,这可能会很慢,因此不要使用它来确定是否安装了命名包(使用 system.file 或 find.包)...”
  • 同意 Thomas,这将是使用 require 而不是检查 installed.packages 的性能更好
  • packrat 就是为此而生的。它是一个可重现的包管理系统。这种方式是以错误的方式进行的,并且会与其他人的环境混为一谈,并且无法重现。 Packrat 拥有自己的共享库文件夹和环境。 rstudio.github.io/packrat
【解决方案2】:

当然。

您需要将“已安装的软件包”与“所需的软件包”进行比较。这与我对CRANberries 所做的非常接近,因为我需要将“存储的已知包”与“当前已知的包”进行比较以确定新的和/或更新的包。

所以做一些类似的事情

AP <- available.packages(contrib.url(repos[i,"url"]))   # available t repos[i]

要获取所有已知的包,模拟调用当前安装的包并将其与一组给定的目标包进行比较。

【讨论】:

    【解决方案3】:

    虽然 Shane 的回答非常好,但对于我的一个项目,我需要删除输出消息、警告并自动安装包。我终于设法得到了这个脚本:

    InstalledPackage <- function(package) 
    {
        available <- suppressMessages(suppressWarnings(sapply(package, require, quietly = TRUE, character.only = TRUE, warn.conflicts = FALSE)))
        missing <- package[!available]
        if (length(missing) > 0) return(FALSE)
        return(TRUE)
    }
    
    CRANChoosen <- function()
    {
        return(getOption("repos")["CRAN"] != "@CRAN@")
    }
    
    UsePackage <- function(package, defaultCRANmirror = "http://cran.at.r-project.org") 
    {
        if(!InstalledPackage(package))
        {
            if(!CRANChoosen())
            {       
                chooseCRANmirror()
                if(!CRANChoosen())
                {
                    options(repos = c(CRAN = defaultCRANmirror))
                }
            }
    
            suppressMessages(suppressWarnings(install.packages(package)))
            if(!InstalledPackage(package)) return(FALSE)
        }
        return(TRUE)
    }
    

    用途:

    libraries <- c("ReadImages", "ggplot2")
    for(library in libraries) 
    { 
        if(!UsePackage(library))
        {
            stop("Error!", library)
        }
    }
    

    【讨论】:

      【解决方案4】:

      我使用以下代码检查是否安装了包以及是否更新了依赖项,然后加载包。

      p<-c('ggplot2','Rcpp')
      install_package<-function(pack)
      {if(!(pack %in% row.names(installed.packages())))
      {
        update.packages(ask=F)
        install.packages(pack,dependencies=T)
      }
       require(pack,character.only=TRUE)
      }
      for(pack in p) {install_package(pack)}
      
      completeFun <- function(data, desiredCols) {
        completeVec <- complete.cases(data[, desiredCols])
        return(data[completeVec, ])
      }
      

      【讨论】:

        【解决方案5】:

        这是rbundler package 的目的:提供一种方法来控制为特定项目安装的包。现在,该包使用 devtools 功能将包安装到您的项目目录。功能类似于 Ruby 的bundler

        如果您的项目是一个包(推荐),那么您所要做的就是加载 rbundler 并捆绑包。 bundle 函数将查看您的包的 DESCRIPTION 文件以确定要捆绑的包。

        library(rbundler)
        bundle('.', repos="http://cran.us.r-project.org")
        

        现在这些包将安装在 .Rbundle 目录中。

        如果您的项目不是一个包,那么您可以通过在项目的根目录中创建一个 DESCRIPTION 文件来伪造它,其中包含列出您要安装的包的 Depends 字段(带有可选的版本信息):

        Depends: ggplot2 (>= 0.9.2), arm, glmnet
        

        如果您有兴趣贡献,这里是该项目的 github 存储库:rbundler

        【讨论】:

          【解决方案6】:

          此解决方案将采用包名称的字符向量并尝试加载它们,或者如果加载失败则安装它们。它依赖于require 的返回行为来执行此操作,因为...

          require返回(不可见的)逻辑,指示所需的包是否可用

          因此,我们可以简单地查看我们是否能够加载所需的包,如果不能,则使用依赖项安装它。所以给定一个你想要加载的包的字符向量......

          foo <- function(x){
            for( i in x ){
              #  require returns TRUE invisibly if it was able to load package
              if( ! require( i , character.only = TRUE ) ){
                #  If package was not able to be loaded then re-install
                install.packages( i , dependencies = TRUE )
                #  Load package after installing
                require( i , character.only = TRUE )
              }
            }
          }
          
          #  Then try/install packages...
          foo( c("ggplot2" , "reshape2" , "data.table" ) )
          

          【讨论】:

          • 安装后你不想再给require打电话吗?
          • @krlmlr 不,因为要评估if 语句,它必须首先评估require,其副作用是加载可用的包!
          • SimonO101:我认为 krlmlr 在 if 语句中的意思是,在调用 install.packages 之后,因为这实际上不会加载该包。但是(对@krlmlr)我怀疑其意图是这个代码片段只会被调用一次;你不会在每次需要这个包的时候都写这个。相反,您可以提前运行一次,然后根据需要像往常一样调用require
          • @Aaron 啊是的,我明白你的意思,是的,你的解释是正确的。我会稍微修改一下,以便在安装后更明确地加载。
          • 将第二个require 调用到library 会不会更好,这样如果由于某种原因仍然无法附加包裹,它会大声失败?
          【解决方案7】:

          你可以只使用require的返回值:

          if(!require(somepackage)){
              install.packages("somepackage")
              library(somepackage)
          }
          

          我在安装后使用library,因为如果安装不成功或由于其他原因无法加载包,它会抛出异常。你使它更加健壮和可重用:

          dynamic_require <- function(package){
            if(eval(parse(text=paste("require(",package,")")))) return True
          
            install.packages(package)
            return eval(parse(text=paste("require(",package,")")))
          }
          

          此方法的缺点是您必须在引号中传递包名称,而对于真正的require,您不会这样做。

          【讨论】:

          • 您可以通过在require 中使用character.only = TRUE 来大大简化您的生活,但我想您的答案与我的答案没有什么不同。
          • 这看起来不错,但似乎不起作用,至少对我来说。当我尝试此功能的强大版本时,我收到两条错误消息,因为 R 出于某种原因不知道如何处理“return True”和“return eval”。所以我真的很想要一个这样的函数,如果我的库中存在一个包,它会加载一个包,否则会安装(然后加载)这个包。理想情况下,我会使用它作为默认加载包。至少看起来这样做是有意义的,并且会节省一些时间。
          【解决方案8】:

          Dason K. 和我有 pacman 包可以很好地做到这一点。包中的函数p_load 就是这样做的。第一行只是为了确保安装了 pacman。

          if (!require("pacman")) install.packages("pacman")
          pacman::p_load(package1, package2, package_n)
          

          【讨论】:

          • 包裹状态如何?我在 C-RAN 上看不到。
          • 现在已经安装好了,效果很好;应该是基地的一部分!
          • 唯一更好的方法是检查/,如果找到,自动从github安装/加载。
          • @NealBarsch 如果你的意思是if (!require("pacman")) install.packages("pacman"),pacman 中有一个名为p_boot() 的函数,它会自动为你生成这一行并将其复制到剪贴板。
          【解决方案9】:

          关于您的主要目标“安装他们还没有的库。”并且无论使用“instllaed.packages()”。下面的函数屏蔽了 require 的原始函数。它会尝试加载并检查命名包 "x" ,如果没有安装,则直接安装它,包括依赖项;最后正常加载。您将函数名称从“require”重命名为“library”以保持完整性。唯一的限制是包名应该被引用。

          require <- function(x) { 
            if (!base::require(x, character.only = TRUE)) {
            install.packages(x, dep = TRUE) ; 
            base::require(x, character.only = TRUE)
            } 
          }
          

          所以你可以用 R 的老式方式加载和安装包。 需要(“ggplot2”) 要求(“Rcpp”)

          【讨论】:

          • 如果您不再喜欢您的答案,请不要破坏它 - 只需将其删除。
          • 嗯,我试过了,但我做不到。我认为我的 FF 的 NoScript 扩展正在禁用它,或者我没有删除我自己的答案的权利和信用。大声笑但是,我认为 Livius 非常接近我的答案,没有掩饰地思考。谢谢迈克尔·佩罗塔。通知。
          • 您应该会在这些 cmets 上方看到一个 delete 链接。如果您不这样做,但仍想删除,请使用 flag 链接,选择“其他”,并向版主说明您希望删除答案。
          【解决方案10】:
          # List of packages for session
          .packages = c("ggplot2", "plyr", "rms")
          
          # Install CRAN packages (if not already installed)
          .inst <- .packages %in% installed.packages()
          if(length(.packages[!.inst]) > 0) install.packages(.packages[!.inst])
          
          # Load packages into session 
          lapply(.packages, require, character.only=TRUE)
          

          【讨论】:

          • 这是我选择的最佳答案。它允许安装多个包,但只安装那些尚未安装的包。
          【解决方案11】:

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

          【讨论】:

            【解决方案12】:

            以下简单的功能就像一个魅力:

              usePackage<-function(p){
                  # load a package if installed, else load after installation.
                  # Args:
                  #   p: package name in quotes
            
                  if (!is.element(p, installed.packages()[,1])){
                    print(paste('Package:',p,'Not found, Installing Now...'))
                    install.packages(p, dep = TRUE)}
                  print(paste('Loading Package :',p))
                  require(p, character.only = TRUE)  
                }
            

            (不是我的,前段时间在网上发现了这个,从那时起就一直在使用它。不确定原始来源)

            【讨论】:

              【解决方案13】:

              这是我的代码:

              packages <- c("dplyr", "gridBase", "gridExtra")
              package_loader <- function(x){
                  for (i in 1:length(x)){
                      if (!identical((x[i], installed.packages()[x[i],1])){
                          install.packages(x[i], dep = TRUE)
                      } else {
                          require(x[i], character.only = TRUE)
                      }
                  }
              }
              package_loader(packages)
              

              【讨论】:

                【解决方案14】:

                如果require("&lt;package&gt;") 退出并出现未找到包的错误,我使用以下函数安装包。它将同时查询 - CRAN 和 Bioconductor 存储库以查找丢失的包。

                改编自 Joshua Wiley 的原作, http://r.789695.n4.nabble.com/Install-package-automatically-if-not-there-td2267532.html

                install.packages.auto <- function(x) { 
                  x <- as.character(substitute(x)) 
                  if(isTRUE(x %in% .packages(all.available=TRUE))) { 
                    eval(parse(text = sprintf("require(\"%s\")", x)))
                  } else { 
                    #update.packages(ask= FALSE) #update installed packages.
                    eval(parse(text = sprintf("install.packages(\"%s\", dependencies = TRUE)", x)))
                  }
                  if(isTRUE(x %in% .packages(all.available=TRUE))) { 
                    eval(parse(text = sprintf("require(\"%s\")", x)))
                  } else {
                    source("http://bioconductor.org/biocLite.R")
                    #biocLite(character(), ask=FALSE) #update installed packages.
                    eval(parse(text = sprintf("biocLite(\"%s\")", x)))
                    eval(parse(text = sprintf("require(\"%s\")", x)))
                  }
                }
                

                例子:

                install.packages.auto(qvalue) # from bioconductor
                install.packages.auto(rNMF) # from CRAN
                

                PS:update.packages(ask = FALSE) & biocLite(character(), ask=FALSE) 将更新系统上所有已安装的软件包。这可能需要很长时间,并将其视为完整的 R 升级,可能并不总是有保证!

                【讨论】:

                【解决方案15】:
                 48 lapply_install_and_load <- function (package1, ...)
                 49 {
                 50     #
                 51     # convert arguments to vector
                 52     #
                 53     packages <- c(package1, ...)
                 54     #
                 55     # check if loaded and installed
                 56     #
                 57     loaded        <- packages %in% (.packages())
                 58     names(loaded) <- packages
                 59     #
                 60     installed        <- packages %in% rownames(installed.packages())
                 61     names(installed) <- packages
                 62     #
                 63     # start loop to determine if each package is installed
                 64     #
                 65     load_it <- function (p, loaded, installed)
                 66     {
                 67         if (loaded[p])
                 68         {
                 69             print(paste(p, "loaded"))
                 70         }
                 71         else
                 72         {
                 73             print(paste(p, "not loaded"))
                 74             if (installed[p])
                 75             {
                 76                 print(paste(p, "installed"))
                 77                 do.call("library", list(p))
                 78             }
                 79             else
                 80             {
                 81                 print(paste(p, "not installed"))
                 82                 install.packages(p)
                 83                 do.call("library", list(p))
                 84             }
                 85         }
                 86     }
                 87     #
                 88     lapply(packages, load_it, loaded, installed)
                 89 }
                

                【讨论】:

                  【解决方案16】:

                  相当基本的一个。

                  pkgs = c("pacman","data.table")
                  if(length(new.pkgs <- setdiff(pkgs, rownames(installed.packages())))) install.packages(new.pkgs)
                  

                  【讨论】:

                    【解决方案17】:

                    认为我会贡献我使用的那个:

                    testin <- function(package){if (!package %in% installed.packages())    
                    install.packages(package)}
                    testin("packagename")
                    

                    【讨论】:

                      【解决方案18】:

                      您可以简单地使用setdiff 函数来获取未安装的软件包,然后安装它们。在下面的示例中,我们在安装之前检查是否安装了 ggplot2Rcpp 包。

                      unavailable <- setdiff(c("ggplot2", "Rcpp"), rownames(installed.packages()))
                      install.packages(unavailable)
                      

                      上面一行可以写成:

                      install.packages(setdiff(c("ggplot2", "Rcpp"), rownames(installed.packages())))
                      

                      【讨论】:

                      • 我使用相同的方法。我们也可以使用installed.packages()[,'Package'] 代替rownames(installed.packages())
                      【解决方案19】:
                      library <- function(x){
                        x = toString(substitute(x))
                      if(!require(x,character.only=TRUE)){
                        install.packages(x)
                        base::library(x,character.only=TRUE)
                      }}
                      

                      这适用于不带引号的包名称并且相当优雅(参见 GeoObserver 的回答)

                      【讨论】:

                        【解决方案20】:
                        if (!require('ggplot2')) install.packages('ggplot2'); library('ggplot2')
                        

                        “ggplot2”是包。它检查是否安装了软件包,如果没有安装它。然后,无论它采用哪个分支,它都会加载包。

                        【讨论】:

                          【解决方案21】:

                          使用packrat,这样共享库就完全一样了,不会改变别人的环境。

                          就优雅和最佳实践而言,我认为您从根本上走错了路。包packrat 专为这些问题而设计。它由 Hadley Wickham 的 RStudio 开发。 packrat 使用自己的目录并在其中安装程序的所有依赖项,而不是安装依赖项并可能弄乱某人的环境系统,而不会触及某人的环境。

                          Packrat 是 R 的依赖管理系统。

                          R 包依赖可能令人沮丧。您是否曾经不得不通过反复试验来确定需要安装哪些 R 包才能使其他人的代码正常工作——然后这些包被永久安装在全局范围内,因为现在您不确定是否需要它们?您是否曾经更新包以使您的一个项目中的代码能够工作,却发现更新的包使另一个项目中的代码停止工作?

                          我们构建了 Packrat 来解决这些问题。使用 packrat 使您的 R 项目更多:

                          • 隔离:为一个项目安装新的或更新的包不会破坏您的其他项目,反之亦然。这是因为 packrat 为每个项目提供了自己的私有包库。
                          • 便携:轻松将您的项目从一台计算机传输到另一台计算机,甚至跨不同平台。 Packrat 让您可以轻松安装项目所依赖的包。
                          • 可重现:Packrat 记录您所依赖的确切软件包版本,并确保无论您走到哪里都能安装这些确切版本。

                          https://rstudio.github.io/packrat/

                          【讨论】:

                            【解决方案22】:

                            上面的很多答案(以及这个问题的重复)都依赖于installed.packages,这是一种不好的形式。来自文档:

                            当安装了数千个包时,这可能会很慢,因此不要使用它来确定是否安装了命名包(使用 system.file 或 find.package),也不要用于确定包是否可用(调用 require并检查返回值)也没有找到少量包的详细信息(使用 packageDescription)。它需要为每个已安装的软件包读取多个文件,这在 Windows 和某些网络安装的文件系统上会很慢。

                            因此,更好的方法是尝试使用require 加载包并在加载失败时安装(require 将返回FALSE,如果未找到)。我更喜欢这个实现:

                            using<-function(...) {
                                libs<-unlist(list(...))
                                req<-unlist(lapply(libs,require,character.only=TRUE))
                                need<-libs[req==FALSE]
                                if(length(need)>0){ 
                                    install.packages(need)
                                    lapply(need,require,character.only=TRUE)
                                }
                            }
                            

                            可以这样使用:

                            using("RCurl","ggplot2","jsonlite","magrittr")
                            

                            这样它会加载所有包,然后返回并安装所有丢失的包(如果需要,它是插入提示询问用户是否要安装包的一个方便的地方)。它不是为每个包单独调用install.packages,而是只传递一次已卸载包的整个向量。

                            这是相同的功能,但带有一个窗口对话框,询问用户是否要安装缺少的软件包

                            using<-function(...) {
                                libs<-unlist(list(...))
                                req<-unlist(lapply(libs,require,character.only=TRUE))
                                need<-libs[req==FALSE]
                                n<-length(need)
                                if(n>0){
                                    libsmsg<-if(n>2) paste(paste(need[1:(n-1)],collapse=", "),",",sep="") else need[1]
                                    print(libsmsg)
                                    if(n>1){
                                        libsmsg<-paste(libsmsg," and ", need[n],sep="")
                                    }
                                    libsmsg<-paste("The following packages could not be found: ",libsmsg,"\n\r\n\rInstall missing packages?",collapse="")
                                    if(winDialog(type = c("yesno"), libsmsg)=="YES"){       
                                        install.packages(need)
                                        lapply(need,require,character.only=TRUE)
                                    }
                                }
                            }
                            

                            【讨论】:

                            • 这是一种非常优雅的方式,比公认的方式要好得多。我会将它包含在我的个人图书馆中。谢谢。
                            【解决方案23】:
                            source("https://bioconductor.org/biocLite.R")
                            if (!require("ggsci")) biocLite("ggsci")
                            

                            【讨论】:

                              【解决方案24】:

                              就我而言,我想要一个可以从命令行(实际上是通过 Makefile)运行的行。以下是安装“VGAM”和“羽毛”的示例(如果尚未安装):

                              R -e 'for (p in c("VGAM", "feather")) if (!require(p, character.only=TRUE)) install.packages(p, repos="http://cran.us.r-project.org")'
                              

                              在 R 中它只是:

                              for (p in c("VGAM", "feather")) if (!require(p, character.only=TRUE)) install.packages(p, repos="http://cran.us.r-project.org")
                              

                              除了以前的解决方案之外,这里没有其他解决方案:

                              • 我只保留一行
                              • 我对@9​​87654321@ 参数进行了硬编码(以避免任何弹出窗口询问要使用的镜像)
                              • 我懒得定义要在别处使用的函数

                              还要注意重要的character.only=TRUE(没有它,require 会尝试加载包p)。

                              【讨论】:

                                【解决方案25】:

                                使用 lapply 系列和匿名函数方法,您可以:

                                1. 尝试附加所有列出的包。
                                2. 仅安装缺失(使用||惰性评估)。
                                3. 尝试再次附加在第 1 步中丢失并在第 2 步中安装的那些。
                                4. 打印每个包的最终加载状态 (TRUE / FALSE)。

                                  req <- substitute(require(x, character.only = TRUE))
                                  lbs <- c("plyr", "psych", "tm")
                                  sapply(lbs, function(x) eval(req) || {install.packages(x); eval(req)})
                                  
                                  plyr psych    tm 
                                  TRUE  TRUE  TRUE 
                                  

                                【讨论】:

                                  【解决方案26】:

                                  即将推出的 RStudio (1.2) 版本已作为预览版提供,将包含一项功能,可检测 library()require() 调用中缺少的包,并提示用户安装它们:

                                  检测丢失的 R 包

                                  许多 R 脚本打开时调用 library()require() 以加载执行所需的包。如果您打开一个引用了您尚未安装的包的 R 脚本,RStudio 现在将提供一次单击即可安装所有需要的包。无需再重复输入install.packages(),直到错误消失!
                                  https://blog.rstudio.com/2018/11/19/rstudio-1-2-preview-the-little-things/

                                  这似乎特别好地解决了 OP 最初的担忧:

                                  他们中的许多人是 R 新手/中级用户,没有意识到他们必须安装他们还没有的软件包。

                                  【讨论】:

                                    【解决方案27】:
                                      packages_installed <- function(pkg_list){
                                            pkgs <- unlist(pkg_list)
                                            req <- unlist(lapply(pkgs, require, character.only = TRUE))
                                            not_installed <- pkgs[req == FALSE]
                                            lapply(not_installed, install.packages, 
                                                   repos = "http://cran.r-project.org")# add lib.loc if needed
                                            lapply(pkgs, library, character.only = TRUE)
                                    }
                                    

                                    【讨论】:

                                      【解决方案28】:

                                      让我分享一点疯狂:

                                      c("ggplot2","ggsci", "hrbrthemes", "gghighlight", "dplyr") %>%  # What will you need to load for this script?
                                        (function (x) ifelse(t =!(x %in% installed.packages()), 
                                          install.packages(x[t]),
                                          lapply(x, require))) 
                                      

                                      【讨论】:

                                        【解决方案29】:

                                        这里几乎所有的答案都依赖于 (1) require() 或 (2) installed.packages() 来检查给定的软件包是否已经安装。

                                        我正在添加一个答案,因为这些对于回答这个问题的轻量级方法来说是不令人满意的。

                                        • require 具有加载包的命名空间的副作用,这可能并不总是可取的
                                        • installed.packages 是点燃蜡烛的火箭筒——它将首先检查 整个世界 已安装的软件包,然后我们检查我们的一个(或几个)软件包是否“有货”图书馆。没有必要为了找针而建草堆。

                                        此答案也受到@ArtemKlevtsov's great answer 的启发,在此问题的重复版本中具有类似的精神。他指出,如果未安装软件包,system.file(package=x) 可以产生返回 '' 的预期效果,否则返回 nchar &gt; 1

                                        如果我们深入了解system.file 是如何实现这一点的,我们可以看到它使用了一个不同的base 函数find.package,我们可以直接使用它:

                                        # a package that exists
                                        find.package('data.table', quiet=TRUE)
                                        # [1] "/Library/Frameworks/R.framework/Versions/4.0/Resources/library/data.table"
                                        
                                        # a package that does not
                                        find.package('InstantaneousWorldPeace', quiet=TRUE)
                                        # character(0)
                                        

                                        我们还可以查看 find.package 的内部结构以了解它是如何工作的,但这主要是一个有指导意义的练习——我看到的简化功能的唯一方法是跳过一些稳健性检查。但基本思路是:查看.libPaths()——任何已安装的软件包pkg 都会在file.path(.libPaths(), pkg) 处有一个DESCRIPTION 文件,因此快速检查是file.exists(file.path(.libPaths(), pkg, 'DESCRIPTION')

                                        【讨论】:

                                        • 经过深入研究的答案!尽管如此,我对模棱两可的返回感到有些困惑:file.exists(file.path(.libPaths(), 'sf', 'DESCRIPTION')) [1] TRUE FALSE。在设计包安装链时我应该只使用第一个 bool 吗?
                                        • @saQuist 是的,IINM 这就是 install.packages 所做的。实际上它可能更像是一个 for 循环,循环 .libPaths() 并在成功后退出
                                        【解决方案30】:
                                        pckg=c("shiny","ggplot2","dplyr","leaflet","lubridate","RColorBrewer","plotly","DT","shinythemes")
                                        
                                        for(i in 1:length(pckg)) 
                                           {
                                              print(pckg[i])
                                              if (!is.element(pckg[i], installed.packages()[,1]))
                                              install.packages(pckg[i], dep = TRUE)
                                              require(pckg[i], character.only = TRUE)
                                        }
                                        

                                        【讨论】:

                                          猜你喜欢
                                          • 1970-01-01
                                          • 2016-11-04
                                          • 1970-01-01
                                          • 2011-03-01
                                          • 1970-01-01
                                          • 2011-08-02
                                          • 1970-01-01
                                          相关资源
                                          最近更新 更多