在R中,调用另一个函数而不评估你给出的参数的惯用方法显然如下:
Call <- match.call(expand.dots = TRUE)
# Modify parameters here as needed and set unneeded ones to NULL.
Call[[1L]] <- as.name("name.of.function.to.be.called.here")
eval.parent(Call)
但是,当我在utils::write.csv
调用中添加命名空间名称(例如as.name()
)时,出现错误:
“找不到函数”utils :: write.csv“
使用此R语法调用命名空间函数的正确方法是什么?
答案 0 :(得分:3)
这是一个使用do.call()
的解决方案,它构造和评估函数调用。
就像你开始使用的方法一样,这个方法使用R调用是列表的事实,其中:(a)第一个元素是函数的名称;和(b)所有后续元素都是该函数的参数。
j <- function(x, file) {
Call <- match.call(expand.dots = TRUE)
arglist <- as.list(Call)[-1]
do.call(utils::write.csv, arglist)
}
dat <- data.frame(x=1:10, y=rnorm(10))
j(dat, file="outfilename.csv")
编辑: FWIW,这是基地R中plot.formula
的示例,它使用类似于上面的结构:
{
m <- match.call(expand.dots = FALSE)
eframe <- parent.frame()
. . .
. . .
m <- as.list(m)
m[[1L]] <- stats::model.frame.default
m <- as.call(c(m, list(na.action = NULL)))
mf <- eval(m, eframe)
. . .
. . .
}
该函数稍后使用do.call()
构造。深入了解杂草,我的阅读是在这里显示的代码段中,它主要是因为需要将na.action=NULL
添加到参数列表中而使用了几个步骤。
在任何情况下,看起来do.call()
选项都尽可能接近规范。
答案 1 :(得分:1)
正如@Josh O'Brien回答的那样,do.call
更加直接使用。
do.call
的第一个参数可以是函数名称,也可以是实际函数。
函数名称可以 NOT 包含名称空间限定符。 ::
部分实际上是一个函数,它在两侧获取名称并找到相应的函数,因此必须单独评估才能工作。
因此,对于do.call
,您需要以下内容:
# ...Stuff from Josh's answer goes here
# And then:
do.call(utils::write.csv, arglist)
使用eval
:
Call <- match.call(expand.dots = TRUE)
# Modify parameters here as needed and set unneeded ones to NULL.
Call[[1L]] <- utils::write.csv
eval.parent(Call)
注意函数名称周围缺少引号。这将评估函数的关闭。
从命名空间限定名称获取函数的另一种方法:
eval(parse(text="utils::write.csv"))
同样,调用正确查找函数的::
函数。
另一种更手动的方法是提取命名空间名称&amp;函数名称,然后自己进行查找:
x <- strsplit("utils::write.csv", "::")[[1]]
get(x[2], asNamespace(x[1]))