【问题标题】:Load a package only when needed in R package仅在 R 包中需要时才加载包
【发布时间】:2023-03-18 18:16:01
【问题描述】:

我有一个包含一大堆杂项功能的包(请参阅What to do with imperfect-but-useful functions?)。因为这些功能不是特别相关,所以它们依赖于一大堆其他包。通常整个包中只有一个函数使用另一个包。然而,如果我在说明文件中使用 Imports、Suggests 或 Depends,则每次加载我的包时都会加载整个包列表,即使任何给定用户需要它们中的很少。

有没有办法只在使用特定功能时才加载依赖项?我可以在函数内部调用library(),但这似乎是一种不好的做法,因为它不会告诉包管理系统任何东西,因此用户可能没有安装它。

【问题讨论】:

    标签: r package


    【解决方案1】:

    您可以使用 Suggests,在需要该包的功能中,您可以将代码添加到 require() 所述包,如果不可用则抛出错误。我熟悉的一个例子是 vegan 包,在它的描述中

    Depends: permute
    Suggests: MASS, mgcv, lattice, cluster, scatterplot3d, rgl, tcltk
    

    在加载我们拥有的包时:

    R> require(vegan)
    Loading required package: vegan
    Loading required package: permute
    This is vegan 1.90-0
    

    sessionInfo() 报告尚未加载/附加任何建议的包等:

    R> sessionInfo()
    R version 2.13.1 Patched (2011-07-29 r56550)
    Platform: x86_64-unknown-linux-gnu (64-bit)
    
    locale:
     [1] LC_CTYPE=en_GB.utf8       LC_NUMERIC=C             
     [3] LC_TIME=en_GB.utf8        LC_COLLATE=en_GB.utf8    
     [5] LC_MONETARY=C             LC_MESSAGES=en_GB.utf8   
     [7] LC_PAPER=en_GB.utf8       LC_NAME=C                
     [9] LC_ADDRESS=C              LC_TELEPHONE=C           
    [11] LC_MEASUREMENT=en_GB.utf8 LC_IDENTIFICATION=C      
    
    attached base packages:
    [1] stats     graphics  grDevices utils     datasets  methods   base     
    
    other attached packages:
    [1] vegan_1.90-0  permute_0.5-0
    
    loaded via a namespace (and not attached):
    [1] tools_2.13.1
    

    【讨论】:

    • 这正是我想要的。谢谢。
    • +1 这个策略可能适合于 misc 包:Suggested 不需要安装包来安装你的包。对于 misc 包,这可能是一个很大的优势。例如。即使 rgl 无法安装在他们的机器上,用户也可以使用 vegan 的非 rgl 部分。在这种情况下,只有使用 rgl 的功能不可用。
    • @cbeleites 这就是 Jari Oksanen(首席素食主义者开发人员)选择使用 Suggests 来处理我们使用的额外软件包的原因。
    • require 更好,您可能想要使用requireNamespace::。有关详细信息,请参阅r-pkgs.had.co.nz/description.html
    【解决方案2】:

    一般来说,我尽量避免在包中使用require()。作为建议,使用命名空间(这并不难)并使用 Imports :没有加载提到的包。您只能通过以下方式从另一个包中导入单个函数:

    • 在命名空间文件中使用importFrom 声明。 importFrom(foo, x, y) 告诉我们应该导入来自包 foo 的函数 xy
    • 在代码中使用双冒号运算符:foo::bar 从包foo 导入函数bar。例如。 plyr::ddply(...) 将在不加载包的情况下访问 ddply 函数
    • 或三冒号运算符,以防未导出的对象 (foo:::bar)

    在所有三种情况下,包都应在 Imports 中提及。另请参阅Writing R Extensions 中的相关章节 1.6 和其他内容。

    编辑:正如@Gavin 指出的那样,这一切仅在从具有自己命名空间的包中导入时才有效。从 R 的下一个版本(2.14?)开始,所有包都应该有一个命名空间。

    【讨论】:

    • +1 这确实假设一个包有一个 NAMESPACE - 现在很多都没有,但在 R 的下一个主要版本中都会有。
    • 请注意,Imports: 中列出的 所有 包必须在用户系统上可用才能安装您的包。另请参阅我对 Gavin 解决方案的评论。
    猜你喜欢
    • 1970-01-01
    • 2016-11-05
    • 2013-10-04
    • 1970-01-01
    • 1970-01-01
    • 2016-12-16
    • 1970-01-01
    • 1970-01-01
    • 2017-08-03
    相关资源
    最近更新 更多