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

What is the difference between require() and library()?

提问人:Marco 提问时间:4/8/2011 最后编辑:zx8754Marco 更新时间:4/13/2021 访问量:168402

问:

和 和有什么不一样?require()library()

R-FAQ

评论

3赞 Chase 4/8/2011
mail-archive.com/[email protected]/msg00301.html
7赞 MichaelChirico 2/4/2016
向 @Yihui 的博客文章添加链接,除非他想发布该博客文章的一个版本作为答案。yihui.name/en/2014/07/library-vs-require
0赞 constra 12/15/2016
如果我想在包加载后返回逻辑值,我通常使用 require。
7赞 De Novo 3/21/2018
总结 @Yihui 的博客文章:“女士们,先生们,我之前说过:require() 是加载 R 包的错误方式;请改用 library() ”
1赞 smci 6/27/2018
@DanHall......因为立即大声、提前地失败,并带有相关的错误消息(如果软件包未安装或无法加载),而不会引发错误,只是静默地返回布尔 FALSE,该 FALSE 被丢弃,并导致代码稍后失败,并且更隐晦地在(比如)第 175 行。library()require()Error: object “bar” not found

答:

385赞 richiemorrisroe 4/8/2011 #1

在日常工作中,这样的人并不多。

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

评论

2赞 Marco 4/8/2011
#richiemorrisroe:谢谢。这是否意味着如果我在 R 代码的开头加载我需要的包,那么我选择哪一个并不重要?
7赞 richiemorrisroe 4/8/2011
只要你不在函数中加载包,它就真的没有区别。我使用 require 加载了我所有的包,直到我看到您的问题后阅读了帮助,才知道有什么区别。
47赞 IRTFM 4/8/2011
我使用的另一个原因是,它使我无法将包称为 ,这种做法将 R-cognoscenti 推向了墙上。是包所在的目录位置。requirelibrarieslibrary
24赞 Konrad Rudolph 9/28/2015
它们有非常相关的差异。不要使用 ,除非您检查返回值(在这种情况下,通常有更好的替代方案,例如 )。requireloadNamespace
276赞 Thierry 4/9/2011 #2

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

> 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

因此,您可以在以下结构中使用。如果您想将代码分发到我们的 R 安装中,这主要很方便,因为包可能没有安装。require()

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")
    }
}
11赞 dsb 10/9/2013 #3

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

评论

21赞 Ben Bolker 5/9/2014
这很有趣,但并不是问题的答案......?
1赞 Script47 7/17/2019
这个答案正在 meta 上讨论。
21赞 dwstu 12/15/2013 #4
?library

你会看到:

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

77赞 Daniel Sparing 8/20/2014 #5

如果想在必要时安装软件包,则可以使用,例如: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)
    }
}

专业提示:

  • 在脚本内部使用时,可以通过指定 的参数来避免对话框屏幕,例如reposinstall.packages()

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

141赞 dww 2/10/2015 #6

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

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

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

5赞 Shape 2/22/2016 #7

这似乎是已经加载的包的区别。 虽然确实 require 和 library 都不会加载包。库在签入和退出之前会做很多其他事情。

无论如何,我建议从运行 2mil 次的函数的开头删除“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

评论

0赞 Konrad Rudolph 7/10/2018
我认为这是修复实现的有力理由(这两个函数,正如目前 R 所附带的那样,都是一团糟)。library
0赞 Shape 7/11/2018
@KonradRudolph好吧,如果有人要修复库,也许他们也可以显式启用按版本加载,并将附件作为参数选项
0赞 Konrad Rudolph 7/11/2018
是的,我完全同意,但这些会改变语义,而不仅仅是性能。无论如何,不幸的是,版本控制永远不会适用于 R 中的包。我正在为此寻找替代品(真的!至于附加,您可以使用 ,它加载一个包并返回其命名空间,而不附加它。loadNamespace
88赞 Konrad Rudolph 7/10/2018 #8

始终使用 .切勿使用 .libraryrequire

tl;DR:打破了健壮软件系统的基本规则之一:尽早失败require

简而言之,这是因为,在使用 时,您的代码可能会产生不同的错误结果,而不会发出错误信号。这种情况很少见,但不是假设的!请考虑以下代码,该代码根据 {dplyr} 是否可以加载而产生不同的结果require

require(dplyr)

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

这可能会导致微妙的错误结果。使用 instead of 在此处抛出错误,明确表示有问题。这很好libraryrequire

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

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

从技术上讲,实际上是在内部调用(如果包尚未附加,则执行冗余检查,因为还会检查包是否已加载)。下面是一个简化的实现,以说明它的作用:requirelibraryrequirelibraryrequire

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}和许多其他软件包的作者说:

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

哈德利·威克姆(Hadley Wickham)是比任何人都更受欢迎的R包的作者,他说

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

评论

0赞 Ghost 10/11/2019
我将指出完全相同的观点,除非您使用语法调用所有函数,否则可以避免这种情况。class::functionlibrary()