aL3*_*3xa 19 namespaces packages r
好吧,我们都熟悉R中的双冒号运算符.每当我要写一些函数时,我都会使用require(<pkgname>)
,但我一直在考虑使用::
.require
在自定义函数中使用是比更好的做法library
,因为require
返回警告,并且FALSE
,library
如果提供不存在的包的名称,则会返回错误.
另一方面,::
操作员从包中获取变量,同时require
加载整个包(至少我希望如此),因此速度差异首先出现在我的脑海中.::
必须快于require
.
我做了一些分析,以便检查 - 我写了两个简单的函数,read.systat
从foreign
包中加载函数require
,::
分别使用和导入Iris.syd
数据集,包含foreign
包,每个复制函数1000次(这是无耻的任意),和. ..打了一些数字.
奇怪(或没有)我发现在用户CPU和经过时间方面存在显着差异,而在系统CPU方面没有显着差异.然而更奇怪的结论::
是:实际上更慢!文档::
是非常生硬的,只是通过查看来源,显然::
应该表现更好!
要求
#!/usr/local/bin/r
## with require
fn1 <- function() {
require(foreign)
read.systat("Iris.syd", to.data.frame=TRUE)
}
## times
n <- 1e3
sink("require.txt")
print(t(replicate(n, system.time(fn1()))))
sink()
Run Code Online (Sandbox Code Playgroud)
双结肠
#!/usr/local/bin/r
## with ::
fn2 <- function() {
foreign::read.systat("Iris.syd", to.data.frame=TRUE)
}
## times
n <- 1e3
sink("double_colon.txt")
print(t(replicate(n, system.time(fn2()))))
sink()
Run Code Online (Sandbox Code Playgroud)
在此处获取 CSV数据.一些统计数据:
user CPU: W = 475366 p-value = 0.04738 MRr = 975.866 MRc = 1025.134
system CPU: W = 503312.5 p-value = 0.7305 MRr = 1003.8125 MRc = 997.1875
elapsed time: W = 403299.5 p-value < 2.2e-16 MRr = 903.7995 MRc = 1097.2005
Run Code Online (Sandbox Code Playgroud)
MRr的平均等级require
,MRc同上::
.我一定做错了.它只是没有任何意义......执行时间::
似乎更快!!! 我可能搞砸了,你不应该放弃那个选择......
好的......我浪费了我的时间,以便看到存在一些差异,并且我进行了完全无用的分析,所以,回到问题:
" 为什么一个喜欢require
在::
写一个函数是什么时候? "
=)
Sha*_*pie 12
"在编写函数时,为什么要优先考虑需要?"
我通常更喜欢require
由于良好的TRUE/FALSE返回值,这让我可以在进入代码之前处理包之前无法提供的可能性.尽可能早地崩溃而不是分析中途.
我只::
在需要确保使用正确版本的函数时使用,而不是使用掩盖名称的其他软件包中的版本.
另一方面,:: operator从包中获取变量,同时需要加载整个包(至少我希望如此),所以速度差异首先出现在我的脑海中.::必须比要求更快.
我认为你可能会忽略包装根据其手册第一页使用的延迟加载的影响.本质上,使用延迟加载的包会延迟对象(如函数)的加载,直到第一次调用对象为止.所以你的论点" 必须比要求更快"并不一定正确,因为当你附上它时不会将所有内容加载到内存中.有关延迟加载的完整详细信息,请参阅Ripley教授在RNews第4卷第2期中的文章.foreign
::
foreign
require
由于加载包的时间几乎总是很小,相比于你花费时间来弄清楚你六个月前编写的代码的时间,在这种情况下,编码的清晰度是最重要的.
对于脚本,打电话require
或library
在开始时让您知道您需要哪些包.
类似地,在函数开头调用require
(或者像requirePackage
in Hmisc
或try_require
in中的包装器ggplot2
)是显示您需要使用该包的最明确的方式.
::
应该保留在包之间有命名冲突的情况 - 比较,例如,
Hmisc::is.discrete
Run Code Online (Sandbox Code Playgroud)
和
plyr::is.discrete
Run Code Online (Sandbox Code Playgroud)