1

我想写一个函数,用字符串指定的参数调用不同的子函数,比如:

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 时,我需要一些方法来传递可选参数。

有谁知道如何处理这个?谢谢。

4

1 回答 1

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))
于 2013-11-05T07:11:40.800 回答