【问题标题】:Function naming for R packagesR 包的函数命名
【发布时间】:2018-01-30 23:06:39
【问题描述】:

我正在编写一个 R 包,并且非常想避免使用在其他包中找到的函数名称。例如,我计划调用一个函数“annotate”,但这已经在 NLP 包中使用了。显然最好避免明显的名称选择,但是否有系统的方法来搜索 CRAN 发布的函数名称的详尽列表以避免重复?我明白这对 CRAN 共享包很重要,但在本地共享时也很重要,以防与另一个加载的包发生冲突。

【问题讨论】:

  • 或许你可以查看here
  • 你可以使用RDocumentation
  • 谢谢,RDocumentation 对于逐个搜索函数名称很有用,我只是想知道某处是否有完整列表,或者有系统地检查函数名称列表的方法?可能没有。谢谢你们的指示!
  • The sos package 可用于搜索您拥有的包之外的内容。另一种选择是为所有函数添加前缀 à la stringi (stri_*)、stringr (str_*) 等。

标签: r function duplicates packages names


【解决方案1】:

当加载两个包含同名函数的包时,会发生名称冲突。因此,可以在两个地方避免名称冲突:

  • 在包中定义函数名称时
  • 从包中调用函数时

创建具有唯一名称的函数

在撰写本文时(2017 年 8 月 23 日),CRAN 上提供了数量惊人的 11272 个软件包(最新数字可以在 here 找到),新软件包是 added every day

因此,今天创建唯一的函数名称可能会在将来添加其他包时导致名称冲突

Alistaire already has mentioned 为所有函数添加前缀的选项。除了stringistringrforcats 包是另一个使用前缀fct_lvls_ 的例子。

这种方法可以大大降低名字冲突的可能性。

(虽然不能保证没有其他包维护者可以选择相同的前缀。)

使用双冒号运算符明确调用函数

恕我直言,避免名称冲突的最终责任在于用户。

我在这里看到了关于 SO 的问题,其中加载了六个以上的包。或者,为方便起见调用了library(tidyverse),它加载了其他19 个包,而dplyrtidyr 本来就足够了。

将命名空间与许多加载的包混淆会增加名称冲突的风险。即使只加载了两个包,也可能发生名称冲突。例如,lubridatedata.table 包都定义了

hour, isoweek, mday, minute, month, quarter, second, wday, week, yday, year

调用哪个函数取决于包的加载顺序。 (您可以使用conflicts() 在搜索路径上的两个或多个位置查找具有相同名称的对象。)

为避免歧义和意外结果,我建议加载尽可能少的包,并使用双冒号运算符?"::" 从包中调用函数,而无需预先加载包,例如,

library(data.table)
DT <- data.table(t = lubridate::now() + 0:3)
# call function from loaded package data.table
DT[, second(t)] 
[1] 18 19 20 21
# call function from lubridate package
DT[, lubridate::second(t)]
[1] 18.88337 19.88337 20.88337 21.88337

使用双冒号运算符还有另一个好处。它将作为代码中的文档,从哪个包中调用函数。

这是以额外的几次击键为代价的,但在数周或数年后检查、修改或调试代码时可能会节省大量时间。我已经看到了很多关于 SO 的问题,其中 OP 没有提到包。

【讨论】:

  • 请注意,使用:: 可能会产生大量开销。在我的系统 x &lt;- runif(100); microbenchmark(sum(x), base::sum(x)) 上它慢了 20 倍(当然,只有 5 微秒),但如果你在 DT[, base::sum(x), by=....] 中对许多组执行此操作,那就有问题了。
  • @Frank 我已经改写了我的答案,以更好地指出我发现前缀是个好主意。感谢您的提示。
  • 感谢大家的回复,我会考虑使用前缀并查看sos包!
猜你喜欢
  • 2013-06-09
  • 2021-09-28
  • 1970-01-01
  • 2012-02-22
  • 2020-06-12
  • 2020-10-01
  • 2018-07-11
  • 2022-11-14
  • 1970-01-01
相关资源
最近更新 更多