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

664

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


3
http://www.mail-archive.com/r-devel@stat.math.ethz.ch/msg00301.html - Chase
7
除非Yihui想把这篇博客作为回答发布,否则请添加一个指向@Yihui博客帖子的链接。http://yihui.name/en/2014/07/library-vs-require/ - MichaelChirico
如果我需要在加载包后返回一个逻辑值,我通常会使用 require。 - constra
7
总结@Yihui的博客文章:"女士们先生们,我以前就说过:require()不是加载R包的正确方式,请使用library()代替之。" - De Novo
1
@DanHall ...因为 library() 会立即失败,输出相关的错误信息(如果包未安装或无法加载),这样可以尽早地发现问题,而 require() 不会引发任何错误,只是静默地返回布尔值 FALSE 被抛弃,导致代码在稍后更加难以理解地失败,并出现“Error: object “bar” not found” (比如在第 175 行)。 - smci
嗨@Marco,这个问题非常受欢迎,正在吸引大量的流量。不幸的是,被接受的答案是(完全)错误的,因为它与通常被接受的最佳实践相矛盾,正如评论和其他答案所解释的那样,并且会误导人们。您是否考虑一下其他答案并接受提供正确解释的答案? (鉴于我是恳求您的人,我建议接受dww的答案,我已经投票支持了。除了我的答案之外,它是唯一指出使用require的严重警告的答案。) - Konrad Rudolph
8个回答

385

在日常工作中,这两者没什么区别。

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


2
#richiemorrisroe:谢谢。这是否意味着,如果我在我的R代码的开头加载我需要的包,那么选择哪个包就无关紧要了? - Marco
7
只要你不在函数内部加载包,实际上并没有什么区别。我使用require加载所有的包,在看到你的问题后阅读了帮助文档才知道有什么不同。 - richiemorrisroe
47
我使用 require 的另一个原因是为了避免把包称作“库”,这样做会让 R 精英们非常恼火。而“库”实际上是指存放包的目录位置。 - IRTFM
24
它们有非常相关的区别。除非您检查返回值(在这种情况下通常有更好的替代方案,例如loadNamespace),否则不要使用“require”。 - Konrad Rudolph

276

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")
    }
}

141
除了已经提供的好建议外,我还要补充以下内容:
最好避免使用require(),除非你实际上会使用它返回的值,例如在一些错误检查循环中,如thierry所给出的。
在大多数其他情况下,最好使用library(),因为这将在包加载时给出错误消息,如果包不可用。如果没有该包,require()仅会失败而不会出现错误。 这是发现包是否需要安装(或者可能不存在,因为拼写错误)的最佳时间。尽早并在相关时间获得错误反馈,将避免跟踪代码失败的可能头疼问题,当它试图使用库例程时。

88

始终使用library,不要使用require

简而言之,这是因为在使用require时,你的代码可能会产生不同的错误结果,而不会发出错误信号。这是罕见但并非假设!考虑以下代码,它会根据是否可以加载{dplyr}来产生不同的结果

tl;dr:require违反了健壮软件系统的基本规则之一:尽早失败

require(dplyr)

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

这可能导致微妙的错误结果。在此处使用library而不是require会抛出错误,清楚地表明出现了问题。这是好的
这也使得调试所有其他失败更加困难:如果你在脚本开头require一个包并在第500行使用它的输出,你将在第500行得到一个“对象‘foo’未找到”的错误消息,而不是一个“没有名为‘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}和许多其他软件包的作者表示:

女士们先生们,我曾经说过:require()是加载R软件包的错误方式;请使用library()。

Hadley Wickham, 比任何其他人都更流行的R软件包的作者,表示

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


我本来也想指出同样的问题,除非你使用 class::function 语法调用所有函数,否则请使用 library() 来避免这种情况。 - Ghost

77

如果您只想在必要时安装包,可以使用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)
    }
}

专业技巧:

  • When used inside the script, you can avoid a dialog screen by specifying the repos parameter of install.packages(), such as

    install.packages(package, repos="http://cran.us.r-project.org")
    
  • You can wrap require() and library() in suppressPackageStartupMessages() to, well, suppress package startup messages, and also use the parameters require(..., quietly=T, warn.conflicts=F) if needed to keep the installs quiet.


21
?library

然后你会看到:

library(package)require(package)都会加载名为package的包并将其放置在搜索列表中。require是设计用于其他函数内部使用; 如果该包不存在,它会返回FALSE并发出警告(而不像默认情况下的library()那样抛出错误)。这两个函数都会检查并更新当前已加载的包列表,并且不会重新加载已经加载过的包。 (如果您想重新加载此类软件包,请先调用detach(unload = TRUE)unloadNamespace。)如果您想要加载一个包而不将其放入搜索列表中,请使用requireNamespace


11

我最初的理论是,library无论其是否已加载,都会加载软件包,即它可能重新加载已经加载的软件包,而require仅检查是否已加载该软件包,如果没有加载,就会加载它(因此在依赖于特定软件包的函数中使用)。 然而,文档驳斥了这一点,并明确表示任何一个函数都不会重新加载已经加载的软件包。


21
这很有趣,但并不真正回答问题的答案...? - Ben Bolker
1
这个答案正在meta上讨论。链接 - Script47

5

这里似乎存在一个已加载包的差异。虽然require和library都不会加载该包,但是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一起提供的两个函数(它们都非常混乱)。 - Konrad Rudolph
@KonradRudolph 好吧,如果有人要修复库,也许可以明确启用按版本加载,并将附件作为参数选项。 - Shape
是的,我完全同意,但这些将更改语义,而不仅仅是性能。无论如何,在 R 中,版本控制永远无法与软件包一起使用,不幸的是。我正在为此工作(真的!)。至于附加,您可以使用 loadNamespace,它加载软件包并返回其名称空间,而不会将其附加。 - Konrad Rudolph

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接