更好地解释何时使用Imports/Depends

SFu*_*n28 134 r

" 写入R扩展 "手册提供了有关何时使用导入或取决的以下指导:

一般规则是

  • 包,其名称空间仅需要加载使用库(PKGNAME)包必须在"进口"字段中列出,而不是在"Depends中"字段.
  • 需要附加以使用库(pkgname)成功加载包的包必须仅在"取决于"字段中列出.

有人可以提供一点清晰度吗?我如何知道我的软件包何时只需要加载名称空间,何时需要附加软件包?两者的例子是什么?我认为典型的包只是一组函数,有时会调用其他包中的函数(其中一些工作已被编码).这个场景是1还是2?

编辑

我写了一篇博文,其中有关于这一特定主题的部分(搜索"Imports v Depends").视觉效果使其更容易理解.

Jos*_*ien 135

"Imports""Depends"使用它的其他软件包更安全(并且还使用它作为'更好的公民'的包装"Depends").

"Depends"指令试图确保从另一程序包的功能是可用的由其它包附加到主搜索路径(即,由返回的环境的列表search()).但是,如果稍后加载的另一个包在搜索路径上更早地放置一个具有相同名称的函数,则可以阻止此策略.Chambers(在SoDA中)使用函数的示例,该函数"gam"可以在gammgcv包中找到.如果其他两个包分别加载,这取决于他们中的一个gam,一个依赖于mgcv通过电话发现功能gam()将取决于其所那两个包分别连接顺序.不好.

一个"Imports"指令放在导入包<imports:packageName>(后立即搜索<namespace:packageName>而不是常规的搜索路径).如果上面示例中的任何一个软件包使用了该"Imports"机制,则可以通过两种方式改进问题.(1)包本身可以控制import使用哪种功能.(2)通过保持主搜索路径不受导入对象的影响,它甚至不会破坏其他包对其他importFrom函数的依赖性.

这就是为什么使用名称空间是一个很好的做法,为什么它现在由CRAN强制执行,并且(特别是)为什么使用NAMESPACE比使用更安全mgcv.


编辑添加一个重要的警告:

上面的建议有一个不幸的常见例外:如果你的包依赖于另一个包mgcv本身的"Imports""Depends",你的包可能需要附加A一个"Depends"指令.

这是因为B中的函数是在期望包A及其函数将附加到"Depends路径的情况下编写的.

一个A指令将加载和附加包B,此时包search()的自身"Depends"指令将在链式反应中导致包A被加载和附加.A然后,包中的函数将能够找到"Depends"它们所依赖的包中的函数.

一个B指令将加载,但重视包装A,将既不加载也不重视包装B.("Imports"毕竟,期望包编写者正在使用命名空间机制,并且该包AB用于指向"Imports"它需要访问的任何函数.)函数调用包A依赖于包中的函数的包中的任何函数"Imports"将因此失败了.

唯一的解决方案是:

  1. 让您的包B使用A指令附加包.
  2. 从长远来看,更好的方法是联系包的维护者,B让他们更仔细地构建他们的命名空间(用相应答案中的Martin Morgan的话来说).


maj*_*jom 29

Hadley Wickham给出了一个简单的解释(http://r-pkgs.had.co.nz/namespace.html):

列出一个包DependsImports确保在需要时安装它.主要区别在于Imports只需加载包装,Depends附加包装.没有其他差异.[...]

除非有很好的理由,否则你应该始终列出的包Imports没有Depends.这是因为一个好的包是自包含的,并且最小化了对全局环境(包括搜索路径)的更改.唯一的例外是如果您的包被设计为与另一个包一起使用.例如,模拟包构建在素食主义者之上.没有素食主义者,它没有用,所以它有素食Depends而不是素食主义者Imports.同样,ggplot2应该真的取决于规模,而不是导入它.


42-*_*42- 14

SfDA中的Chambers表示当这个包使用'命名空间'机制时使用'Imports',并且因为现在所有包都需要它们,所以现在答案可能总是使用'​​Imports'.在过去,可以在没有实际拥有命名空间的情况下加载包,在这种情况下,您需要使用Depends.

  • +1 - 这也是我的强烈印象.此外,导入中指定的包将在`<namespace:packageName>`之后立即搜索,作为`<imports:packageName>`的一部分.不需要进一步调用`library()`,除非找不到`Import`ed包,否则R不会在包加载时通过控制台通知你. (4认同)
  • 当在"imports"中指定一个包并且我想在包中使用一个函数时,我自己的函数需要调用库(...)还是搜索路径中已经存在的所有函数?另外,什么是SfDA?链接? (2认同)
  • *数据分析软件*:http://www.springer.com/statistics/computanional+statistics/book/978-0-387-75935-7 ...至于你的问题,我不知道答案的答案,但你可以很容易地破解一个最小的测试包,并根据经验找到答案...... (2认同)

Aar*_*ley 6

这是一个简单的问题,可帮助您决定使用哪个:

您的包是否要求最终用户直接访问另一个包的功能?

  • 否 -> 进口(最常见的答案)
  • 是 -> 取决于

您应该使用“Depends”的唯一时间是当您的包是另一个包的附加组件或伴侣时,您的最终用户将在其代码中同时使用您的包和“Depends”包中的函数。如果您的最终用户只与您的函数交互,而另一个包只在幕后工作,那么请改用“导入”。

对此的警告是,如果像通常那样将包添加到“导入”,则您的代码将需要使用完整的命名空间语法(例如dplyr::mutate(),而不是仅mutate(). 它使代码阅读起来有点笨拙,但为了更好的包装卫生而付出的代价很小。