5

我想要do.call一个包中的(导出的)函数,并且需要在what参数中将包和函数指定为字符串(即,当包未加载到我的环境中或存在潜在的函数名称冲突时)。

"lme4::lmer"函数名是指定包和函数的字符串

例如,有条件地调用一个函数(类似于这个问题):

FUN = if(TRUE) {
  "lme4::lmer"
} else {
  "nlme::nmle"
}

args.list = list(Reaction ~ Days + (Days | Subject), 
                 quote(lme4::sleepstudy))

do.call(what=FUN, args=args.list)
# Error in `lme4::lmer`(Reaction ~ Days + (Days | Subject), lme4::sleepstudy) : 
#   could not find function "lme4::lmer"

其他方式有效,但不是我需要的:

# Load the package and use only the function string 
library(lme4)
do.call("lmer", ...)

# Or calling the function directly: 
lme4::lmer(...)
4

2 回答 2

10

您不能包含::在字符串中,因为::它是一个函数。该字符串不会被评估和解析。do.call只是假设存在该名称的函数。就像::,$也是一个函数,所以这也不起作用

a<-list(f=function(x) x+1)
do.call(a$f, list(4))
# [1] 5
do.call("a$f", list(4))
# Error in do.call("a$f", list(4)) : could not find function "a$f"

如果您希望能够从命名空间中找到函数,您可以编写一个帮助函数,当它们包含时解析值::

getfun<-function(x) {
    if(length(grep("::", x))>0) {
        parts<-strsplit(x, "::")[[1]]
        getExportedValue(parts[1], parts[2])
    } else {
        x
    }
}
getfun("lme4::lmer")

这应该有效

do.call(getfun("lme4::lmer"), list(
    Reaction ~ Days + (Days | Subject), 
    quote(lme4::sleepstudy)))
于 2016-08-16T20:48:59.530 回答
2
do.call(eval(parse(text="lme4::lmer")), ...)

带有解析的 eval 将起作用!

> tmp <- expand.grid(letters[1:2], 1:3, c("+", "-"))
> do.call(eval(parse(text='stringr::str_c')), c(tmp, sep = ""))

 [1] "a1+" "b1+" "a2+" "b2+" "a3+" "b3+" "a1-" "b1-" "a2-" "b2-" "a3-" "b3-"

参考:https ://www.r-bloggers.com/converting-a-string-to-a-variable-name-on-the-fly-and-vice-versa-in-r/

于 2016-08-16T20:20:56.380 回答