仅在R包中需要时加载包

Ari*_*man 13 r package

我有一个包含一大堆杂项功能的包(请参阅如何处理不完美但有用的功能?).因为这些功能并不是特别相关,所以它们依赖于一大堆其他包.通常在整个包中只有一个函数使用另一个包.然而,如果我在DESCRIPTION文件中使用Imports,Suggests或Depends,每次加载包时都会加载整个包列表,即使任何给定用户只需要很少的包.

有没有办法只在使用特定函数时加载依赖项?我可以library()自己调用函数内部,但这似乎是不好的做法,因为它没有告诉包管理系统什么,因此用户可能没有安装它.

Rei*_*son 16

您可以使用Suggests,并且在需要该包的函数中,您可以向require()所述包添加代码,如果不可用则抛出错误.我熟悉的一个例子,纯素包,在其描述中

Depends: permute
Suggests: MASS, mgcv, lattice, cluster, scatterplot3d, rgl, tcltk
Run Code Online (Sandbox Code Playgroud)

加载包装时我们有:

R> require(vegan)
Loading required package: vegan
Loading required package: permute
This is vegan 1.90-0
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

  • +1这个策略可能是misc包的合适策略:为了安装你的包,不需要安装`Suggest`ed包.对于misc包,这可能是一个很大的优势.例如,即使rgl无法安装在他们的机器上,用户也可以使用素食主义者的非rgl部分.在这种情况下,只有rgl-using功能不可用. (4认同)

Jor*_*eys 15

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

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

在所有三种情况下,应在Imports中提及包.另请参阅编写R扩展中的相关章节1.6和其他内容.

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

  • 请注意,"Imports:"中列出的*all*软件包必须在用户的系统上可用才能安装软件包.另请参阅我对Gavin解决方案的评论. (3认同)
  • +1这确实假设一个包有一个NAMESPACE - 现在很多都没有,但是所有的都将是R的下一个主要版本. (2认同)