在R中的命名空间中导入有什么好处?

时间:2011-09-02 12:04:09

标签: r namespaces package

R的命名空间机制允许一个export函数,然后用户可以看到它们。此外,它允许来自其他包的import函数。虽然出口的好处是显而易见的,但我在理解进口的好处方面存在更多问题。

似乎有一个好处,即可以使用其他软件包中的函数而无需附加软件包,从而节省内存。这在1.6.4 in the writing R extensions manual部分中举例说明。

但是,导入功能必须具有其他好处。特别是,section 1.6.6 (that deals with S4 classes)显示了stats4包的namespace

 export(mle)
 importFrom("graphics", plot)
 importFrom("stats", optim, qchisq)
 ## For these, we define methods or (AIC, BIC, nobs) an implicit generic:
 importFrom("stats", AIC, BIC, coef, confint, logLik, nobs, profile,
            update, vcov)
 exportClasses(mle, profile.mle, summary.mle)
 ## All methods for imported generics:
 exportMethods(coef, confint, logLik, plot, profile, summary, show, update, vcov)
 ## implicit generics which do not have any methods here
 export(AIC, BIC, nobs)

这里导入的函数既不是S4类也不是泛型(使用导入也是有意义的,如that section中的示例所述),但函数如plot来自R启动时自动加载的graphics包。

因此,我的问题是,导入plotoptimqchisq等功能有什么好处?

1 个答案:

答案 0 :(得分:23)

如果从包Bar导入函数foo,则无论用户对其搜索路径做什么,都会找到它,例如,通过附加也具有函数foo的包Baz。如果没有名称空间,包代码会突然发现自己使用Baz::foo。还有效率问题(foo是立即找到的,而不是在搜索搜索路径上的所有符号之后),但对于大多数应用程序来说,这些问题可能很简单。同样,importFrom是对import的改进,因为更少的冲突(或使用非预期的功能)和更有效的查找。

使用S4(和S3),事情会变得非常复杂。像graphics::plot这样的非泛型函数可以在两个不同的包中提升为泛型(带setGeneric),每个泛型都可以附加自己的一组方法。包作者需要准确了解哪个plot泛型,以及哪些方法调度表,它们的类和方法都可以看到。

调用pkg::foo的函数始终会解析为预期的函数。它要求pkg列在DESCRIPTION文件的Depends:字段中(可能在Imports中:但是它似乎误导了广告而不是从pkg导入),污染了用户的搜索路径。它还涉及两个符号查找和一个函数调用(::),因此效率较低。对我来说,懒惰和缺乏关注细节部分也会使用::作为单调乏味且容易出错。

codetoolsBioC(通过带有用户名和密码readonly的svn)可以从现有包中生成NAMESPACE文件(或者至少可以在最近对R-devel进行更改之前在包上引入NAMESPACE没有一个;我没有在这样的包上尝试过codetoolsBioC。)