6

For long and repeating models I want to create a "macro" (so called in Stata and there accomplished with global var1 var2 ...) which contains the regressors of the model formula.

For example from

library(car)
lm(income ~ education + prestige, data = Duncan)

I want something like:

regressors <- c("education", "prestige")
lm(income ~ @regressors, data = Duncan)  

I could find is this approach. But my application on the regressors won't work:

reg = lm(income ~ bquote(y ~ .(regressors)), data = Duncan)

as it throws me:

Error in model.frame.default(formula = y ~ bquote(.y ~ (regressors)), data =
Duncan,  :  invalid type (language) for variable 'bquote(.y ~ (regressors))'

Even the accepted answer of same question:

lm(formula(paste('var ~ ', regressors)), data = Duncan)

strikes and shows me:

Error in model.frame.default(formula = formula(paste("var ~ ", regressors)),
: object is not a matrix`. 

And of course I tried as.matrix(regressors) :)

So, what else can I do?

4

2 回答 2

8

对于您描述的场景,regressors在全局环境中,您可以使用:

lm(as.formula(paste("income~", paste(regressors, collapse="+"))), data = 
Duncan)

或者,您可以使用一个函数:

modincome <- function(regressors){
    lm(as.formula(paste("income~", paste(regressors, collapse="+"))), data = 
Duncan)  
}

modincome(c("education", "prestige"))
于 2017-10-07T02:10:13.767 回答
8

这里有一些替代方案。前 3 个中没有使用任何包。

1) 重新制定

fo <- reformulate(regressors, response = "income")
lm(fo, Duncan)

或者您可能希望这样写最后一行,以便输出中显示的公式看起来更好:

do.call("lm", list(fo, quote(Duncan)))

在这种情况下,输出的 Call: 行按预期显示,即:

Call:
lm(formula = income ~ education + prestige, data = Duncan)

2) lm(数据帧)

lm( Duncan[c("income", regressors)] )

Call: 输出的行如下所示:

Call:
lm(formula = Duncan[c("income", regressors)])

但我们可以使用以下代码使其看起来与do.call(1) 中的解决方案完全相同:

fo <- formula(model.frame(income ~., Duncan[c("income", regressors)]))
do.call("lm", list(fo, quote(Duncan)))

3) 点

类似于@jenesaisquoi 在评论中建议的替代方法是:

lm(income ~., Duncan[c("income", regressors)])

(2) 中讨论的调用方法:输出也适用于此。

4) fn$ 在函数前面加上 fn$ 可以在其参数中启用字符串插值。此解决方案与问题中显示的使用 $ 代替 @ 执行替换的所需语法几乎相同,并且灵活的替换可以很容易地扩展到更复杂的场景。代码中的quote(Duncan)可以写成 justDuncan并且它仍然会运行,但是lm如果你使用quote(Duncan).

library(gsubfn)

rhs <- paste(regressors, collapse = "+")
fn$lm("income ~ $rhs", quote(Duncan))

Call: 行看起来与do.call上面的解决方案几乎相同——只有间距和引号不同:

Call:
lm(formula = "income ~ education+prestige", data = Duncan)

如果你想要它完全一样,那么:

fo <- fn$formula("income ~ $rhs")
do.call("lm", list(fo, quote(Duncan)))
于 2017-10-07T02:40:08.920 回答