如何在不评估您提供的参数的情况下调用命名空间函数?

时间:2011-11-30 21:33:57

标签: r

在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语法调用命名空间函数的正确方法是什么?

2 个答案:

答案 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]))