将包和函数称为另一个函数中的参数
我试图在R中的不同包中找到针对特定功能的方法.例如, methods(broom :: tidy)
将在其中返回函数 tidy
的所有方法包 broom
.对于我当前的问题,最好在另一个函数中使用 methods
函数,如下所示: f1<-函数(x,y){方法(x :: y)}
I am trying to find methods for specific functions across different packages in R. For example methods(broom::tidy)
will return all methods for the function tidy
in the package broom
. For my current issue it would be better if I could have the methods
function in another function like so:
f1 <- function(x,y){
methods(x::y)
}
(我删除了与问题无关的其他代码部分.)但是,当我运行这样的函数时:
(I removed other parts of the code that are not relevant to my issue.) However when I run the function like this:
f1 <- function(x,y){ methods(x::y)}
f1(broom,tidy)
我收到错误
loadNamespace(name)中的错误:没有名为"x"的包
Error in loadNamespace(name) : there is no package called ‘x’
如果我尝试将其修改为仅更改功能但将软件包保持不变,则会收到类似的错误消息:
If I try to modify it as to only change the function but keep the package the same I get a similar error :
f2 <- function(y){ methods(broom::y)}
f2(tidy)
错误:"y"不是从"namespace:broom"导出的对象
Error: 'y' is not an exported object from 'namespace:broom'
如何获取包和函数名称以在函数中正确评估?当 r
试图评估/替换函数中的值时,当前问题是否与之相关?
How can I get the package and function name to evaluate properly in the function? Does this current issue have to do with when r
is trying to evaluate/substitute values in the function?
::
和 methods()
函数都使用非标准评估才能工作.这意味着您需要更加聪明地将值传递给函数,才能使其正常工作.这是一种方法
Both the ::
and methods()
functions use non-standard evaluation in order to work. This means you need to be a bit more clever with passing values to the functions in order to get it to work. Here's one method
f1 <- function(x,y){
do.call("methods", list(substitute(x::y)))
}
f1(broom,tidy)
在这里,我们使用 substitute()
进行扩展,并将传递到名称空间查找中的 x
和 y
值.这就解决了您可以在其中看到的 ::
部分
Here we use substitute()
to expand and x
and y
values we pass in into the namespace lookup. That solves the ::
part which you can see with
f2 <- function(x,y){
substitute(x::y)
}
f2(broom,tidy)
# broom::tidy
我们需要替换项,因为很可能会有一个带有功能 y
的软件包 x
.因此,使用 ::
时不会扩展变量.请注意,如果您另外需要使用字符值从名称空间中提取值,则 ::
只是 getExportedValue()
的包装.
We need the substitute because there could very well be a package x
with function y
. For this reason, variables are not expanded when using ::
. Note that ::
is just a wrapper to getExportedValue()
should you otherwise need to extract values from namespaces using character values.
但是还有另外一个问题: methods()
不评估其参数,它使用原始表达式来找到方法.这意味着我们实际上并不需要 broom :: tidy
的值,而是传递该文字表达式.由于我们需要评估替换项以获得所需的表达式,因此我们需要使用 do.call()
构建调用以评估 substitute
并传递该表达式转到 methods()
But there is one other catch: methods()
doesn't evaluate it's parameters, it uses the raw expression to find the methods. This means we don't actually need the value of broom::tidy
, we to pass that literal expression. Since we need to evaluate the substitute to get the expression we need, we need to build the call with do.call()
in order to evaluate the substitute
and pass that expression on to methods()