jay*_*.sf 18 r substitution lm stata stata-macros
对于长模型和重复模型,我想创建一个"宏"(所谓的Stata,并在那里完成global var1 var2 ...),其中包含模型公式的回归量.
例如来自
library(car)
lm(income ~ education + prestige, data = Duncan)
Run Code Online (Sandbox Code Playgroud)
我想要的东西:
regressors <- c("education", "prestige")
lm(income ~ @regressors, data = Duncan)
Run Code Online (Sandbox Code Playgroud)
我能找到这种方法.但我在回归量上的应用不起作用:
reg = lm(income ~ bquote(y ~ .(regressors)), data = Duncan)
Run Code Online (Sandbox Code Playgroud)
因为它抛出了我:
Error in model.frame.default(formula = y ~ bquote(.y ~ (regressors)), data =
Duncan, : invalid type (language) for variable 'bquote(.y ~ (regressors))'
Run Code Online (Sandbox Code Playgroud)
即使是同一问题的公认答案:
lm(formula(paste('var ~ ', regressors)), data = Duncan)
Run Code Online (Sandbox Code Playgroud)
罢工并告诉我:
Error in model.frame.default(formula = formula(paste("var ~ ", regressors)),
: object is not a matrix`.
Run Code Online (Sandbox Code Playgroud)
当然我试过as.matrix(regressors):)
那么,我还能做些什么呢?
G. *_*eck 20
这是一些替代方案.前3个没有使用包.
1)重新制定
fo <- reformulate(regressors, response = "income")
lm(fo, Duncan)
Run Code Online (Sandbox Code Playgroud)
或者您可能希望将最后一行写为此,以便输出中显示的公式看起来更好:
do.call("lm", list(fo, quote(Duncan)))
Run Code Online (Sandbox Code Playgroud)
在这种情况下,输出的Call:行显示为预期,即:
Call:
lm(formula = income ~ education + prestige, data = Duncan)
Run Code Online (Sandbox Code Playgroud)
2)lm(数据帧)
lm( Duncan[c("income", regressors)] )
Run Code Online (Sandbox Code Playgroud)
输出的Call:行如下所示:
Call:
lm(formula = Duncan[c("income", regressors)])
Run Code Online (Sandbox Code Playgroud)
但我们可以do.call使用以下代码使其与(1)中的解决方案完全一致:
fo <- formula(model.frame(income ~., Duncan[c("income", regressors)]))
do.call("lm", list(fo, quote(Duncan)))
Run Code Online (Sandbox Code Playgroud)
3)点
类似于@jenesaisquoi在评论中提出的替代方案是:
lm(income ~., Duncan[c("income", regressors)])
Run Code Online (Sandbox Code Playgroud)
(2)中对Call:输出中讨论的方法也适用于此处.
4)fn $ 使用fn $预设函数可在其参数中启用字符串插值.这个解决方案与问题中显示的所需语法几乎相同,使用$代替@来执行替换,灵活的替换可以很容易地扩展到更复杂的场景.该quote(Duncan)代码可以写成只Duncan和它仍然会运行,但呼叫:在显示lm输出会更好看,如果你使用quote(Duncan).
library(gsubfn)
rhs <- paste(regressors, collapse = "+")
fn$lm("income ~ $rhs", quote(Duncan))
Run Code Online (Sandbox Code Playgroud)
Call:行看起来几乎与do.call上面的解决方案相同- 只有间距和引号不同:
Call:
lm(formula = "income ~ education+prestige", data = Duncan)
Run Code Online (Sandbox Code Playgroud)
如果你想要它绝对相同那么:
fo <- fn$formula("income ~ $rhs")
do.call("lm", list(fo, quote(Duncan)))
Run Code Online (Sandbox Code Playgroud)
小智 12
对于您描述的场景,regressors全局环境中的位置,您可以使用:
lm(as.formula(paste("income~", paste(regressors, collapse="+"))), data =
Duncan)
Run Code Online (Sandbox Code Playgroud)
或者,您可以使用一个函数:
modincome <- function(regressors){
lm(as.formula(paste("income~", paste(regressors, collapse="+"))), data =
Duncan)
}
modincome(c("education", "prestige"))
Run Code Online (Sandbox Code Playgroud)