R写作风格 - 需要与::

aL3*_*3xa 19 namespaces packages r

好吧,我们都熟悉R中的双冒号运算符.每当我要写一些函数时,我都会使用require(<pkgname>),但我一直在考虑使用::.require在自定义函数中使用是比更好的做法library,因为require返回警告,并且FALSE,library如果提供不存在的包的名称,则会返回错误.

另一方面,::操作员从包中获取变量,同时require加载整个包(至少我希望如此),因此速度差异首先出现在我的脑海中.::必须快于require.

我做了一些分析,以便检查 - 我写了两个简单的函数,read.systatforeign包中加载函数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::foreignrequire


Ric*_*ton 6

由于加载包的时间几乎总是很小,相比于你花费时间来弄清楚你六个月前编写的代码的时间,在这种情况下,编码的清晰度是最重要的.

对于脚本,打电话requirelibrary在开始时让您知道您需要哪些包.

类似地,在函数开头调用require(或者像requirePackagein Hmisctry_requirein中的包装器ggplot2)是显示您需要使用该包的最明确的方式.

:: 应该保留在包之间有命名冲突的情况 - 比较,例如,

Hmisc::is.discrete
Run Code Online (Sandbox Code Playgroud)

plyr::is.discrete
Run Code Online (Sandbox Code Playgroud)