R 写作风格 - 要求 vs. ::

Posted

技术标签:

【中文标题】R 写作风格 - 要求 vs. ::【英文标题】:R writing style - require vs. :: 【发布时间】:2011-05-21 07:19:07 【问题描述】:

好的,我们都熟悉R中的双冒号运算符。每当我要编写一些函数时,我都会使用require(<pkgname>),但我一直在考虑使用::。在自定义函数中使用requirelibrary 更好,因为require 返回警告和FALSE,不像library,如果你提供一个不存在的包的名称会返回错误。

另一方面,:: 运算符从包中获取变量,而require 加载整个包(至少我希望如此),所以我首先想到的是速度差异。 :: 必须比 require 快。

我做了一些分析以检查 - 我编写了两个简单的函数,从 foreign 包加载 read.systat 函数,分别使用 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()

双冒号

#!/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()

获取 CSV 数据 here。一些统计数据:

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

MRr 是require 的平均排名,MRc 同上::。我一定在这里做错了什么。它只是没有任何意义......:: 的执行时间似乎更快!我可能搞砸了,你不应该放弃那个选项......

好吧...我浪费了我的时间来看看有什么不同,我进行了完全无用的分析,所以,回到问题:

为什么在编写函数时应该更喜欢require 而不是::

=)

【问题讨论】:

这是针对独立函数还是包中的函数? 另外,您通常会在脚本顶部使用一次 require(),而不是在每个函数调用中都使用一次。 用于独立功能。我正在开发一个 Web 应用程序,并且由于 RApache 在每个 HTTP 请求时都会启动新的 R 会话,因此我试图避免不必要的服务器负载。这个例子是不合适的——一旦你导入一个文件,工作就完成了,但是在一个带有一堆 AJAX 调用的交互式 webapp 中,这可能是非常低效的。 【参考方案1】:

"为什么人们更喜欢 require 而不是 :: 写函数的时候?”

我通常更喜欢require,因为它有很好的 TRUE/FALSE 返回值,这让我可以在进入代码之前处理包不可用的可能性。尽早崩溃,而不是进行到一半的分析。

当我需要确保我使用的是正确版本的函数,而不是来自其他包中的掩盖名称的版本时,我只使用::

另一方面,:: 运算符得到 包中的变量,而 需要加载整个包(至少 我希望如此),所以速度差异来了 我首先想到的。 :: 必须更快 超过要求。

我认为您可能忽略了foreign 包根据the first page of its manual 使用的延迟加载 的影响。本质上,使用延迟加载的包会延迟对象(例如函数)的加载,直到对象第一次被调用。因此,您关于“:: 必须比要求快”的论点不一定正确,因为当您使用require 附加它时,foreign 并未将其所有内容加载到内存中。有关延迟加载的完整详细信息,请参阅 RNews 第 4 卷第 2 期中的Prof. Ripley's article。

【讨论】:

你说的太对了……这可能是依赖包的问题。哦,谢谢你的参考。【参考方案2】:

由于与您试图弄清楚六个月前编写的代码内容所花费的时间相比,加载一个包的时间几乎总是很短,因此在这种情况下,为了清晰而编码是最重要的。

对于脚本,在开始时调用requirelibrary 可以让您立即知道需要哪些包。

同样,在函数开头调用require(或Hmisc 中的requirePackageggplot2 中的try_require 之类的包装器)是表明您需要使用该包的最明确的方式.

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

Hmisc::is.discrete

plyr::is.discrete

【讨论】:

以上是关于R 写作风格 - 要求 vs. ::的主要内容,如果未能解决你的问题,请参考以下文章

雅思写作大作文Advantage VS. Disadvantage

解析DBA英国毕业论文的写作规范要求

Typora收费?搭建VS Code MarkDown写作环境

Typora收费?搭建VS Code MarkDown写作环境

Typora收费?搭建VS Code MarkDown写作环境

学术版R论文写作!网络模型拟合实战1