在 R 的命名空间中导入有啥好处?
Posted
技术标签:
【中文标题】在 R 的命名空间中导入有啥好处?【英文标题】:What is the benefit of import in a namespace in R?在 R 的命名空间中导入有什么好处? 【发布时间】:2011-11-09 03:13:11 【问题描述】: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 类也不是泛型(使用 import 也是有意义的,如 that section 中的示例所述),但是像 plot
这样的函数来自 graphics
包在 R 启动时自动加载。
因此我的问题是,导入 plot
、optim
或 qchisq
等函数有什么好处?
【问题讨论】:
【参考方案1】:如果从包 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)。
【讨论】:
也就是说,导入这样的函数只有在想要将其提升为泛型时才有意义? (如果想假设在名为plot
的搜索路径中没有其他函数)
导入您的包使用的函数(从 base 以外的包,始终可用)总是有意义的,否则当某些第 3 个包定义函数 plot = function (...) "I have a good story to tell"
时,您的代码会中断。您无法控制搜索路径,但用户可以。
如果我总是使用::
运算符调用函数(例如,总是graphics::plot()
而不是plot()
),如果已经附加了一个包,导入还有什么好处吗?跨度>
@Martin Morgan:我不确定能得到一切。我发布了另一个与此相关的问题。你能看看吗? ***.com/questions/8501906/…
@Henrik 使用 :: 运算符并不总是有效,例如 raster::plot。此外,如果包已经附加,它可能会不必要地冗长,尽管具体说明函数命名空间通常有利于可移植性。以上是关于在 R 的命名空间中导入有啥好处?的主要内容,如果未能解决你的问题,请参考以下文章
std::literals::.. 作为内联命名空间有啥好处?
将控制器/模型/基本上所有内容添加到自己的命名空间有啥好处?