【问题标题】:What is the difference between require() and library()?require() 和 library() 有什么区别?
【发布时间】:2011-08-01 12:25:19
【问题描述】:

require()library() 有什么区别?

【问题讨论】:

  • 添加@Yihui 博客文章的链接,除非他想发布一个版本作为答案。 yihui.name/en/2014/07/library-vs-require
  • 如果我想在包加载后返回一个逻辑值,我通常使用 require。
  • 总结@Yihui的博文:“女士们,先生们,我之前说过:require()是错误的R包加载方式;使用library()代替”
  • @DanHall ... 因为library() 立即响亮地提前失败,并带有相关的错误消息(如果未安装或无法加载包),而require() 没有引发错误,只是默默地返回被丢弃的布尔值 FALSE,并导致代码稍后失败,并且在(比如说)第 175 行使用Error: object “bar” not found 更加神秘。

标签: r package r-faq


【解决方案1】:

日常工作中没有太多的事情。

但是,根据这两个函数的文档(通过在函数名称前加上? 并按回车键访问),require 用于函数内部,因为它会输出警告并在找不到包时继续,而library 会抛出错误。

【讨论】:

  • #richiemorrisroe:谢谢。这是否意味着如果我在我的 R 代码的一开始就加载我需要的包,我选择哪一个并不重要?
  • 只要你不在函数内加载包,它真的没有区别。我使用 require 加载了我所有的包,直到我在看到你的问题后阅读帮助时才知道有什么区别。
  • 我使用require 的另一个原因是它使我无法将包称为libraries,这种做法将R-cognoscenti 推向了高潮。 library 是包所在的目录位置。
  • 他们有非常相关的差异。不要使用require除非您检查返回值(在这种情况下,通常会有更好的选择,例如loadNamespace)。
【解决方案2】:

require() 的另一个好处是它默认返回一个逻辑值。 TRUE 如果包已加载,FALSE 如果未加载。

> test <- library("abc")
Error in library("abc") : there is no package called 'abc'
> test
Error: object 'test' not found
> test <- require("abc")
Loading required package: abc
Warning message:
In library(package, lib.loc = lib.loc, character.only = TRUE, logical.return = TRUE,  :
  there is no package called 'abc'
> test
[1] FALSE

所以你可以在下面这样的结构中使用require()。如果您想将代码分发到我们的 R 安装中,这主要是方便的,可能未安装软件包。

if(require("lme4")){
    print("lme4 is loaded correctly")
} else {
    print("trying to install lme4")
    install.packages("lme4")
    if(require(lme4)){
        print("lme4 installed and loaded")
    } else {
        stop("could not install lme4")
    }
}

【讨论】:

    【解决方案3】:

    除了已经给出的好的建议,我还要补充一点:

    最好避免使用require()除非您实际上将使用它返回的值,例如在一些错误检查循环中,例如由 thierry 给出的。

    在大多数其他情况下,最好使用library(),因为如果包不可用,这将在包加载时给出错误消息。如果包不存在,require() 将失败而不会出现错误。这是确定是否需要安装软件包(或者甚至可能不存在,因为它拼写错误)的最佳时机。在相关时间及早获得错误反馈将避免在尝试使用库例程时跟踪后来的代码失败的原因

    【讨论】:

      【解决方案4】:

      如果您想在必要时安装软件包,您可以使用require(),例如:

      if (!require(package, character.only=T, quietly=T)) {
          install.packages(package)
          library(package, character.only=T)
      }
      

      你可以使用多个包

      for (package in c('<package1>', '<package2>')) {
          if (!require(package, character.only=T, quietly=T)) {
              install.packages(package)
              library(package, character.only=T)
          }
      }
      

      专业提示:

      • 在脚本内部使用时,可以通过指定install.packages()repos参数来避免出现对话框画面,比如

        install.packages(package, repos="http://cran.us.r-project.org")
        
      • 您可以将require()library() 包装在suppressPackageStartupMessages() 中,以抑制软件包启动消息,如果需要,还可以使用参数require(..., quietly=T, warn.conflicts=F) 来保持安装安静。

      【讨论】:

        【解决方案5】:

        始终使用library。永远不要使用require

        tl;dr:require 打破了稳健软件系统的基本规则之一:fail early

        简而言之,这是因为在使用 require 时,您的代码可能会产生不同的错误结果,不会发出错误信号。这是罕见的,但不是假设的!考虑一下这段代码,它会产生不同的结果,具体取决于是否可以加载 {dplyr}:

        require(dplyr)
        
        x = data.frame(y = seq(100))
        y = 1
        filter(x, y == 1)
        

        这可能会导致微妙的错误结果。使用library 而不是require 会在此处引发错误,清楚地表明有问题。 This is good.

        它还使调试所有其他故障变得更加困难:如果您在脚本开头require 一个包并在第 500 行使用它的导出,您将收到一条错误消息“object 'foo' not found”第 500 行,而不是错误“没有名为 'bla' 的包”。

        require 唯一可接受的用例是立即检查其返回值,正如其他一些答案所示。这是一种相当常见的模式,但即使在这些情况下,最好(并且建议,见下文)将存在检查和包的加载分开。即:在这些情况下使用requireNamespace 而不是require

        从技术上讲,require 实际上在内部调用了library(如果尚未附加该包 - require 因此会执行冗余检查,因为library 检查包是否已经加载)。下面是 require 的简化实现来说明它的作用:

        require = function (package) {
            already_attached = paste('package:', package) %in% search()
            if (already_attached) return(TRUE)
            maybe_error = try(library(package, character.only = TRUE)) 
            success = ! inherits(maybe_error, 'try-error')
            if (! success) cat("Failed")
            success
        }
        

        经验丰富的 R 开发人员同意:

        Yihui Xie,{knitr}、{bookdown} 和许多其他软件包的作者says

        女士们先生们,我之前说过:require() 是加载 R 包的错误方法;改用 library()

        Hadley Wickham,比其他任何人都更受欢迎的 R 包的作者,说

        在数据分析脚本中使用library(x)。 […] 你永远不需要使用require()requireNamespace() 几乎总是更好)

        【讨论】:

        • 我的意思是完全一样的,除非你用class::function的语法调用所有的函数,使用library()来避免这种情况。
        【解决方案6】:
        ?library
        

        你会看到:

        library(package)require(package) 都加载带有名称的包 package 并将其放入搜索列表。 require 专为使用而设计 在其他功能内部;它返回FALSE 并给出警告(而不是 比library() 默认情况下的错误)如果包没有 存在。这两个函数都检查并更新当前加载的列表 包,并且不要重新加载已经加载的包。 (如果你 想重新加载这样的包,请致电detach(unload = TRUE)unloadNamespace 首先。)如果你想加载一个包而不放 在搜索列表中,使用requireNamespace

        【讨论】:

          【解决方案7】:

          我关于差异的最初理论是library 加载包是否已经加载,即它可能重新加载一个已经加载的包,而require 只是检查它是否已加载,或者如果它加载它不是(因此在依赖于某个包的函数中使用)。然而,文档驳斥了这一点,并明确指出这两个函数都不会重新加载已经加载的包。

          【讨论】:

          【解决方案8】:

          这似乎是已加载包的差异。 确实,require 和 library 都不会加载包。库在检查和退出之前还做了很多其他事情。

          无论如何,我建议从运行 200 万次的函数的开头删除“require”,但如果出于某种原因我需要保留它。 require 在技术上是一种更快的检查。

          microbenchmark(req = require(microbenchmark), lib = library(microbenchmark),times = 100000)
          Unit: microseconds
           expr    min     lq      mean median     uq        max neval
            req  3.676  5.181  6.596968  5.655  6.177   9456.006 1e+05
            lib 17.192 19.887 27.302907 20.852 22.490 255665.881 1e+05
          

          【讨论】:

          • 我认为这是修复实现 library 的一个强有力的理由(这两个函数,目前与 R 一起提供,都是一团糟)。
          • @KonradRudolph 好吧,如果有人要修复库,也许他们也可以显式启用按版本加载并将附件作为参数选项
          • 是的,我完全同意,但这些会改变语义,而不仅仅是性能。无论如何,不​​幸的是,版本控制永远不会与 R 中的包一起使用。我正在寻找一个替代品(真的!)。至于附加,你可以使用loadNamespace,它加载一个包并返回它的命名空间,而不附加它。
          猜你喜欢
          • 1970-01-01
          • 2013-03-06
          • 2013-05-16
          • 2017-06-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多