¿Cómo creo una "macro" para regresores en R?
stata substitution (2)
Para modelos largos y repetitivos, quiero crear una "macro" (llamada en Stata y realizada con
global var1 var2 ...
) que contiene los
regresores
de la fórmula del modelo.
Por ejemplo de
library(car)
lm(income ~ education + prestige, data = Duncan)
Quiero algo como:
regressors <- c("education", "prestige")
lm(income ~ @regressors, data = Duncan)
Podría encontrar este enfoque . Pero mi aplicación en los regresores no funcionará:
reg = lm(income ~ bquote(y ~ .(regressors)), data = Duncan)
como me arroja
Error in model.frame.default(formula = y ~ bquote(.y ~ (regressors)), data =
Duncan, : invalid type (language) for variable ''bquote(.y ~ (regressors))''
Incluso la respuesta aceptada de la misma pregunta:
lm(formula(paste(''var ~ '', regressors)), data = Duncan)
huelgas y me muestra:
Error in model.frame.default(formula = formula(paste("var ~ ", regressors)),
: object is not a matrix`.
Y, por supuesto, probé
as.matrix(regressors)
:)
Entonces, ¿qué más puedo hacer?
Aquí hay algunas alternativas. No se utilizan paquetes en los primeros 3.
1) reformular
fo <- reformulate(regressors, response = "income")
lm(fo, Duncan)
o puede que desee escribir la última línea como esta para que la fórmula que se muestra en la salida se vea mejor:
do.call("lm", list(fo, quote(Duncan)))
en cuyo caso la línea Call: de la salida aparece como se esperaba, a saber:
Call:
lm(formula = income ~ education + prestige, data = Duncan)
2) lm (marco de datos)
lm( Duncan[c("income", regressors)] )
La llamada: la línea de salida se ve así:
Call:
lm(formula = Duncan[c("income", regressors)])
pero podemos hacer que se vea exactamente como en la solución
do.call
en (1) con este código:
fo <- formula(model.frame(income ~., Duncan[c("income", regressors)]))
do.call("lm", list(fo, quote(Duncan)))
3) punto
Una alternativa similar a la sugerida por @jenesaisquoi en los comentarios es:
lm(income ~., Duncan[c("income", regressors)])
El enfoque discutido en (2) a la Llamada: salida también funciona aquí.
4) fn $
Prefacing una función con fn $ habilita la interpolación de cadenas en sus argumentos.
Esta solución es casi idéntica a la sintaxis deseada que se muestra en la pregunta usando $ en lugar de @ para realizar la sustitución y la sustitución flexible podría extenderse fácilmente a escenarios más complejos.
La
quote(Duncan)
en el código podría escribirse solo como
Duncan
y aún se ejecutará, pero la Llamada: que se muestra en la salida
lm
se verá mejor si usa la
quote(Duncan)
.
library(gsubfn)
rhs <- paste(regressors, collapse = "+")
fn$lm("income ~ $rhs", quote(Duncan))
La línea Call: se ve casi idéntica a las soluciones
do.call
anteriores, solo el espacio y las comillas difieren:
Call:
lm(formula = "income ~ education+prestige", data = Duncan)
Si lo querías absolutamente igual, entonces:
fo <- fn$formula("income ~ $rhs")
do.call("lm", list(fo, quote(Duncan)))
Para el escenario que describió, donde los
regressors
encuentran en el entorno global, puede usar:
lm(as.formula(paste("income~", paste(regressors, collapse="+"))), data =
Duncan)
Alternativamente, podría usar una función:
modincome <- function(regressors){
lm(as.formula(paste("income~", paste(regressors, collapse="+"))), data =
Duncan)
}
modincome(c("education", "prestige"))