r stata substitution lm stata-macros

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