我想编写一个函数,并使用string指定的参数调用不同的子函数,例如:
genericModel <- function(model, dat, y, x, ...) {
fit <- get(model)(get(y) ~ get(x), data = dat, ...)
return(fit)
}
我能够使用简单的案例:
> d <- data.frame(x.var = rnorm(10), y.var = rnorm(10), w = rep(1, 10))
> genericModel('lm', d, 'y.var', 'x.var')
Call:
get(model)(formula = get(y) ~ get(x), data = dat)
Coefficients:
(Intercept) get(x)
-0.04242 -0.31619
但是,我在通过字符串传递其他可选参数方面没有成功:
> genericModel('lm', d, 'y.var', 'x.var', weights = 'w')
Error in model.frame.default(formula = get(y) ~ get(x), data = dat, weights = "w", :
variable lengths differ (found for '(weights)')
我知道我可以做genericModel('lm', d, 'y.var', 'x.var', weights = d$w)
,但是这会破坏创建灵活函数的目的,我可以通过字符串指定模型和列名。
此外,我可以预见到可选参数包括data.frame(例如weights = w
)的列名和子函数的通用选项(例如:na.action=na.pass
)的复杂性。
编辑: 只是为了澄清,我希望实现的目标是:
genericModel('lm', d, 'y.var', 'x.var', weights = 'w')
genericModel('glm', d, 'y.var', 'x.var', family = 'binomial')
分别运行线性回归和逻辑回归。在调用genericModel时,我需要一些方法来传递可选参数。
有谁知道如何处理这个问题?感谢。
答案 0 :(得分:2)
一个建议:你应该做的是传递公式,而不是摆弄字符串来指定分析变量。这也更灵活,因为您可以将复杂的模型公式直接传递给底层函数而无需任何解析。
如果你这样做,那么通过一些语言黑客来获得你想要的东西很简单。获取对函数的调用,然后对其进行操作以调用模型拟合函数。
genericModel <- function(mod, formula, data, ...)
{
cl <- match.call(expand=TRUE)
cl[[1]] <- cl$mod
cl$mod <- NULL
eval(cl, parent.frame())
}
genericModel(lm, mpg ~ hp, data=mtcars, weights=gear)
genericModel(glm, Volume ~ Girth + Height, data=trees, family=Gamma(link=log))