如何创建一个"宏"对于R的回归量?

时间:2017-10-07 00:58:44

标签: r stata substitution lm stata-macros

对于漫长而重复的模型,我想创建一个"宏" (所谓的Stata,并在那里完成了global var1 var2 ...),其中包含模型公式的 regressors

例如来自

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

我想要类似的东西:

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

我找到的是this approach。但我对回归量的应用却没有成功:

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

因为它抛出了我:

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

即使是同一问题的接受答案:

lm(formula(paste('var ~ ', regressors)), data = Duncan)
罢工并告诉我:

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

当然我试过as.matrix(regressors):)

那么,我还能做些什么呢?

2 个答案:

答案 0 :(得分:10)

对于您所描述的场景,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"))

答案 1 :(得分:9)

以下是一些替代方案。前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)])

但我们可以使用此代码使其与(1)中的do.call解决方案完全一致:

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)中讨论的Call:输出方法也适用于此。

4)fn $ 使用fn $预设函数可在其参数中启用字符串插值。这个解决方案与问题中显示的所需语法几乎相同,使用$代替@来执行替换,灵活的替换可以很容易地扩展到更复杂的场景。代码中的quote(Duncan)可以只写为Duncan,它仍然可以运行,但如果您使用lmquote(Duncan)输出中显示的Call:会更好。< / p>

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)))