【问题标题】:How do I create a "macro" for regressors in R?如何在 R 中为回归量创建“宏”?
【发布时间】:2018-03-18 20:20:42
【问题描述】:

对于长且重复的模型,我想创建一个包含模型公式的回归量的“宏”(在 Stata 中称为,并通过 global var1 var2 ... 完成)。

例如来自

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

那么,我还能做什么?

【问题讨论】:

  • 只需在该问题上使用其他答案。我不确定 bquote 适应可变数量的协变量有多容易。
  • @joran:也没有用,我在我的问题中说明了错误消息,现在我也做了一些更可重复的操作。
  • 下面有几个演示我提到的答案是如何工作的。不要那么轻易放弃! ;)
  • 顺便说一句,因为我们不应该称它为“宏”,我们如何在 R 中调用它?
  • FWIW,使用像这样的global 来保存变量名称在 Stata 社区中被广泛认为是不好的风格。在需要知道的基础上,有许多更好的方法可以在程序或命令或其他代码块之间传递名称列表。

标签: r stata substitution lm stata-macros


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    这里有一些替代方案。前 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:
    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 在 cmets 中建议的替代方法是:

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

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

    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: 输出,您的第一名是我的。可能其他解决方案也可以通过某种方式进行改进。
    • 我已在 Call: output 中添加了所有解决方案的信息。
    猜你喜欢
    • 2023-04-08
    • 2018-06-27
    • 2018-08-07
    • 1970-01-01
    • 2018-07-29
    • 2012-05-04
    • 2018-02-26
    • 2021-12-26
    • 2022-01-12
    相关资源
    最近更新 更多