require()和library()的区别是什么?


在日常工作中,“一”并不多。

然而,根据这两个函数的文档(通过输入?在函数名和按enter键之前),require在函数内部使用,因为它会输出一个警告,如果没有找到包则继续,而library将抛出一个错误。


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

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


?library

你会看到:

library(package) and require(package) both load the package with name package and put it on the search list. require is designed for use inside other functions; it returns FALSE and gives a warning (rather than an error as library() does by default) if the package does not exist. Both functions check and update the list of currently loaded packages and do not reload a package which is already loaded. (If you want to reload such a package, call detach(unload = TRUE) or unloadNamespace first.) If you want to load a package without putting it on the search list, use requireNamespace.


你可以使用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参数来避免出现对话框屏幕,例如 安装。包(包,回购= " http://cran.us.r-project.org ") 你可以在suppressPackageStartupMessages()中包装require()和library()来抑制包启动消息,也可以使用参数require(…,安静=T,警告。冲突=F)如果需要保持安装安静。


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

最好避免使用require(),除非你真的要使用它返回的值,例如在一些错误检查循环中,比如thierry给出的。

In most other cases it is better to use library(), because this will give an error message at package loading time if the package is not available. require() will just fail without an error if the package is not there. This is the best time to find out if the package needs to be installed (or perhaps doesn't even exist because it it spelled wrong). Getting error feedback early and at the relevant time will avoid possible headaches with tracking down why later code fails when it attempts to use library routines


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

无论如何,我建议将“require”从运行2mil次的函数的开头删除,但如果出于某种原因,我需要保留它。从技术上讲,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

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

require打破了健壮软件系统的基本规则之一:及早失败。

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

require(dplyr)

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

这可能会导致微妙的错误结果。使用library而不是require会在这里抛出一个错误,清楚地表明出了错误。这很好。

这也使得调试所有其他失败更加困难:如果你在脚本开始时需要一个包,并在第500行中使用它的导出,你将在第500行中得到一个错误消息“object ' foo ' not found”,而不是错误“there is no package called ' bla '”。

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

从技术上讲,require实际上在内部调用库(如果包还没有被附加,require会执行冗余检查,因为库也会检查包是否已经被加载)。下面是一个简化的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开发人员同意:

{knitr}、{bookdown}等多款软件包的作者谢一辉说:

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

哈德利•维克汉姆(Hadley Wickham)是最受欢迎的R软件包的作者

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