首页 文章

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

提问于
浏览
465

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

9 回答

  • 57

    日常工作中没有多少人 .

    但是,根据两个函数的文档(通过在函数名称之前放置 ? 并按Enter键访问),函数内部使用 require ,因为它输出警告并在未找到包时继续,而 library 将抛出错误 .

  • 6

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

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

    Pro tips:

    • 在脚本中使用时,可以通过指定 install.packages()repos 参数来避免对话框屏幕,例如
    install.packages(package, repos="http://cran.us.r-project.org")
    
    • 您可以在 suppressPackageStartupMessages() 中包装 require()library() ,以及抑制包启动消息,并且如果需要还可以使用参数 require(..., quietly=T, warn.conflicts=F) 来保持安装的安静 .
  • 50

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

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

    在大多数其他情况下,最好使用 library() ,因为如果程序包不可用,这将在程序包加载时给出错误消息 . 如果包不存在, require() 将失败而没有错误 . 这是查看是否需要安装软件包的最佳时间(或者甚至可能因为拼写错误而不存在) . 在相关时间尽早获得错误反馈可以避免在尝试使用库例程时追踪以后代码失败的原因时可能出现的问题

  • 2
    ?library
    

    你会看到:

    library(package)和require(package)都使用name包加载包并将其放在搜索列表中 . require设计用于其他功能;如果包不存在,它返回FALSE并发出警告(而不是像库()默认情况下的错误) . 这两个函数都检查并更新当前加载的包列表,并且不重新加载已加载的包 . (如果要重新加载此类包,请先调用detach(unload = TRUE)或unloadNamespace . )如果要加载包而不将其放在搜索列表中,请使用requireNamespace .

  • 15

    始终使用库 . 从不使用要求 .

    (1几乎没有 . 也许 . )

    简而言之,这是因为,当使用 require 时,您的代码可能会产生不同的错误结果,而不会发出错误信号 . 这很少见,但不是假设!请考虑此代码,根据是否可以加载,会产生不同的结果:

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

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

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

    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的作者,和许多其他软件包says

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

    Hadley Wickham,比其他人更受欢迎的R套餐的作者说

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

  • 300

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

  • 230

    这里似乎是已加载包的差异 . 虽然require和library都没有加载包 . 图书馆在检查和退出之前会做很多其他事情 .

    我建议从运行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
    
  • -8

    require() 加载所有其他包

相关问题