我正在编写一些R函数,使用了其他包中的一些有用函数,如stringr
和base64enc
。不调用library(...)
或require(...)
来先加载这些包,而是使用::
直接引用我需要的函数,例如stringr::str_match(...)
,这样做好吗?
总体上,这样做是一个好习惯吗?或者可能会引发什么问题呢?
我正在编写一些R函数,使用了其他包中的一些有用函数,如stringr
和base64enc
。不调用library(...)
或require(...)
来先加载这些包,而是使用::
直接引用我需要的函数,例如stringr::str_match(...)
,这样做好吗?
总体上,这样做是一个好习惯吗?或者可能会引发什么问题呢?
::
。当我加载dplyr
包时,它提供了一个filter
函数,与默认加载在stats
包中的filter
函数发生冲突并遮蔽了后者。因此,如果我想在加载dplyr
之后使用stats
版本的函数,则需要使用stats::filter
进行调用。::
而不是加载整个包,特别是如果您知道该包将屏蔽其他要使用的函数。::
非常有用。键入stats::filter
比"从stats
包中获取filter
函数"更简洁。::
会有一个(非常)小的代价。R核心开发团队成员Martin Maechler在r-devel邮件列表(2017年9月)上写道:
性能惩罚非常小,大约几微秒,因此只有在需要高度优化的代码时才需要关注。运行使用许多人似乎忘记了每次使用
::
都是一个R函数调用,并且与仅使用已导入名称相比使用它是低效的。
::
的一百万行代码将比不使用::
的代码慢一两秒钟。Aside
: 有类似的论点认为应该选择library()
而不是require()
。如果包不存在,Library会导致错误并停止,而Require会发出警告但继续执行。如果你的代码在包不存在情况下有备选计划,请使用if (require(package)) ...
,但如果你的代码没有包将会失败,你应该在顶部使用library(package)
,以便早日清晰明了地失败。
一般的解决方案是在DESCRIPTION文件中制作自己的包,从而导入需要在其中使用的其他包。当你的包被安装时,这些包将自动安装,因此你可以在内部使用pkg::fun
。或者,在NAMESPACE文件中也导入它们,你可以导入整个包或选择性地导入特定函数,而不需要::
。对此有不同的意见。马丁·梅克勒(与上面相同的R-devel来源)说:
::
不再使用。pkg::fun()
明确地引用它。除非有充分的理由不这样做,否则最好明确地指定。”Hmisc
包中借用了%nin%
函数,因为我认为这是一个很棒的函数,但我很少使用Hmisc
中的其他内容。使用roxygen2
,可以轻松地添加@author
和@references
来正确归属所借用的函数的代码。在这样做时,请确保软件包许可证是兼容的。library(...)
的另一个好处是,如果有人在未安装包的情况下尝试source
您的文件,则source
命令会很早失败(而不是在潜在的长时间数据加载或操作之后才失败)。 - Hughstop
或warning
而不是cat
。 - Gregor Thomas::
而不是命名空间导入或importsFrom(除非你从其他包中使用了很多函数)。 - hadley
require
通常在包中的函数中使用,这个SO帖子很好地区分了它和library
之间的区别。如果你确定只需要一个(或两个)包中的函数,则使用::
就可以了,但是当命名空间发生冲突时,我只会选择::
。还有,不要忘记:::
运算符。 - hrbrmstr