如何在R中为回归器创建“宏”?

7

对于长期和重复性的模型,我希望创建一个“宏”(在Stata中称为如下完成:global var1 var2 ...),其中包含模型公式中的自变量

例如,从以下公式:

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

我希望你能提供以下类似的内容:

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

我能找到的是这个方法。但我的回归器应用无法工作:
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) :)

那么,还有什么其他的我可以做的吗?


只需使用该问题中的其他答案。我不确定bquote在适应可变协变量数量方面会有多容易。 - joran
@joran:还是没有起作用,我在我的问题中提到了错误消息,现在我也让它更易于重现了。 - jay.sf
1
顺便问一下,既然我们不应该称其为“宏”,那么在R中我们该如何称呼它? - jay.sf
1
就此而言,在Stata社区中,使用类似这样的“global”来保存变量名已被广泛废弃,因为它是不良风格。有许多更好的方法可以在需要知道的情况下在程序、命令或其他代码块之间传递名称列表。 - Nick Cox
我期望得到一个回归器名称的字符串列表。通常情况下,你不需要将其设置为全局变量。 - smci
显示剩余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"))

8
以下是一些替代方案。前三个没有使用任何软件包。 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(dataframe)

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

@jenesaisquoi在评论中提出的一种类似的替代方案是:

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

在(2)中讨论的方法对于输出Call也适用于此处。

4) fn$ 在函数前加上fn$,可以启用其参数中的字符串插值。该解决方案与问题中所示的期望语法几乎相同,只需将@替换为$以执行替换,并且灵活的替换可以轻松扩展到更复杂的情况。代码中的quote(Duncan)可以写成Duncan,它仍然会运行,但如果使用quote(Duncan),则在lm输出中显示的Call会更好看一些。

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

由于最清晰的 Call: 输出,你的第一名是我的。很可能其他解决方案也可以在某种程度上得到改进。 - jay.sf
1
我已经为所有解决方案添加了有关“调用: 输出”的信息。 - G. Grothendieck

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接