【问题标题】:Determining which version of a function is active when many packages are loaded在加载许多包时确定哪个版本的函数处于活动状态
【发布时间】:2021-09-02 16:04:05
【问题描述】:

如果我加载了多个定义同名函数的包,是否有一种简单的方法可以确定当前哪个版本的函数是活动的?比如,假设我已经加载了基础 R、tidyverse 和一堆时间序列包。我想要一个函数which_package("intersect"),它可以告诉我 intersect 函数的活动版本的包名称。我知道您可以返回查看安装软件包时收到的所有警告消息,但我认为这种手动搜索不仅乏味而且容易出错。

有一个函数here 可以满足我的要求,但它会为所有冲突生成一个表,而不是为一个函数生成一个值。我实际上会对此感到非常满意,并且也会接受类似的功能作为答案,但是我对给定功能的实现有疑问。在我的示例中,它插入了大量的空格和许多重复的包名称(例如 %>% 函数显示列出了 132 个包),使得输出难以阅读和使用。删除空白和重复项似乎应该很容易,而且我已经花了相当多的时间在我希望工作但对结果没有影响的各种方法上。

所以,举个很多冲突的例子:

install.packages(pkg = c("tidyverse", "fpp3", "tsbox", "rugarch", "Quandl", "DREGAR", "dynlm", "zoo", "GGally", "dyn", "ARDL", "bigtime", "BigVAR", "dLagM", "VARshrink")

lapply(x = c("tidyverse", "fable", "tsbox", "rugarch", "Quandl", "DREGAR", "dynlm", "zoo", "GGally", "dyn", "ARDL", "bigtime", "BigVAR", "dLagM", "VARshrink"), 
library, character.only = TRUE)

【问题讨论】:

  • 你试过conflicts()吗?

标签: r package scoping conflicting-libraries


【解决方案1】:

您可以使用自己的函数助手提取此信息。

which_package <- function(fun) {
  if(is.character(fun)) fun <- getFunction(fun)
  stopifnot(is.function(fun))
  x <- environmentName(environment(fun))
  if (!is.null(x)) return(x)
}

这将为您在全局环境中定义的函数返回 R_GlobalEnv。还有packageName 函数,如果你真的想把它限制在包中。 例如

library(MASS)
library(dplyr)
which_package(select)
# [1] "dplyr"

【讨论】:

  • 谢谢弗利克先生!我刚刚在“intersect”上尝试了这个函数,我在上面引用的函数报告在 tsibble、lubridate、dplyr 和 base 中定义。我不认为 lubridate 是由我上面设置的包加载的——我相信 tsibble 是由 fpp3 加载的。但是当我在它上面运行你的函数时,当函数作为字符串传递时,我得到了一个空字符串 "",当我将它作为未引用函数传递时,我得到了 [1] "generics"。
  • @andrewH 这期望被传递的函数是一个不带引号的函数名。 “泛型”是实际定义函数的地方。 dplyr 版本只是重新导出该版本。许多 tidyverse 库使用“generics”包来为最初未定义为泛型函数的基本函数定义泛型方法。这就是实际运行的功能,所以我会说它工作正常。
  • 啊!我很尴尬地承认,我什至不知道有一个名为 generics 的包。我只是认为这是一个功能描述。我很高兴拥有这个功能,而不仅仅是因为它明显的实用性。这是我第一次使用我自己没有命名的环境名称。元编程又迈出了一小步。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-30
  • 1970-01-01
  • 1970-01-01
  • 2018-07-04
相关资源
最近更新 更多