首页 > 解决方案 > 将包和函数称为另一个函数中的参数

问题描述

我试图在 R 中的不同包中找到特定函数的方法。例如,将返回包中methods(broom::tidy)函数的所有方法。对于我当前的问题,如果我可以在另一个函数中使用该函数会更好,如下所示: tidybroommethodsf1 <- function(x,y){ methods(x::y) }

(我删除了与我的问题无关的其他代码部分。)但是当我像这样运行函数时:

f1 <- function(x,y){ methods(x::y)}
f1(broom,tidy)

我得到错误

loadNamespace(name) 中的错误:没有名为“x”的包

如果我尝试将其修改为仅更改功能但保持包相同,我会收到类似的错误:

f2 <- function(y){  methods(broom::y)}
f2(tidy)

错误:“y”不是从“命名空间:broom”导出的对象

如何获取包和函数名称以在函数中正确评估?当前的问题是否与何时r尝试评估/替换函数中的值有关?

标签: rfunction

解决方案


::和函数都methods()使用非标准评估才能工作。这意味着您需要更聪明地向函数传递值才能使其工作。这是一种方法

f1 <- function(x,y){ 
  do.call("methods", list(substitute(x::y)))
}
f1(broom,tidy)

在这里,我们使用substitute()扩展和x传入y命名空间查找的值。这解决了::你可以看到的部分

f2 <- function(x,y){ 
  substitute(x::y)
}
f2(broom,tidy)
# broom::tidy

我们需要替代品,因为很可能有一个x带有 function的包y。因此,使用::. 请注意,如果您需要使用字符值从命名空间中提取值,这::只是一个包装器。getExportedValue()

但是还有另一个问题:methods()不评估它的参数,它使用原始表达式来查找方法。这意味着我们实际上不需要 的值broom::tidy,我们可以传递该文字表达式。由于我们需要评估替换来获得我们需要的表达式,我们需要构建调用do.call()以评估substitute并将该表达式传递给methods()


推荐阅读