tipos - ¿Cómo escribir sucintamente una fórmula con muchas variables de un marco de datos?
variable dependiente (6)
Construyo esta solución, reformulate
no me importa si los nombres de variables tienen espacios en blanco.
add_backticks = function(x) {
paste0("`", x, "`")
}
x_lm_formula = function(x) {
paste(add_backticks(x), collapse = " + ")
}
build_lm_formula = function(x, y){
if (length(y)>1){
stop("y needs to be just one variable")
}
as.formula(
paste0("`",y,"`", " ~ ", x_lm_formula(x))
)
}
# Example
df <- data.frame(
y = c(1,4,6),
x1 = c(4,-1,3),
x2 = c(3,9,8),
x3 = c(4,-4,-2)
)
# Model Specification
columns = colnames(df)
y_cols = columns[1]
x_cols = columns[2:length(columns)]
formula = build_lm_formula(x_cols, y_cols)
formula
# output
# "`y` ~ `x1` + `x2` + `x3`"
# Run Model
lm(formula = formula, data = df)
# output
Call:
lm(formula = formula, data = df)
Coefficients:
(Intercept) x1 x2 x3
-5.6316 0.7895 1.1579 NA
`` `
Supongamos que tengo una variable de respuesta y un dato que contiene tres covariables (como un ejemplo de juguete):
y = c(1,4,6)
d = data.frame(x1 = c(4,-1,3), x2 = c(3,9,8), x3 = c(4,-4,-2))
Quiero ajustar una regresión lineal a los datos:
fit = lm(y ~ d$x1 + d$x2 + d$y2)
¿Hay alguna manera de escribir la fórmula, para que no tenga que escribir cada covariable individual? Por ejemplo, algo así como
fit = lm(y ~ d)
(Quiero que cada variable en el marco de datos sea una covariable). Pregunto porque en realidad tengo 50 variables en mi marco de datos, así que quiero evitar escribir x1 + x2 + x3 + etc
Hay un identificador especial que uno puede usar en una fórmula para significar todas las variables, es el .
identificador.
y <- c(1,4,6)
d <- data.frame(y = y, x1 = c(4,-1,3), x2 = c(3,9,8), x3 = c(4,-4,-2))
mod <- lm(y ~ ., data = d)
También puede hacer cosas como esta, para usar todas las variables, una barra:
mod <- lm(y ~ . - x3, data = d)
Técnicamente,. significa todas las variables no mencionadas en la fórmula . Por ejemplo
lm(y ~ x1 * x2 + ., data = d)
donde .
solo haría referencia a x3
ya que x1
y x2
ya están en la fórmula.
Puede verificar los leaps
del paquete y, en particular, las funciones regsubsets()
para la selección del modelo. Como se indica en la documentación:
Selección del modelo mediante búsqueda exhaustiva, paso a paso hacia adelante o hacia atrás, o reemplazo secuencial
Sí, por supuesto, simplemente agregue la respuesta y
como primera columna en el marco de datos y llame a lm()
sobre él:
d2<-data.frame(y,d)
> d2
y x1 x2 x3
1 1 4 3 4
2 4 -1 9 -4
3 6 3 8 -2
> lm(d2)
Call:
lm(formula = d2)
Coefficients:
(Intercept) x1 x2 x3
-5.6316 0.7895 1.1579 NA
Además, mi información acerca de R indica que la asignación con <-
se recomienda sobre =
.
Un enfoque ligeramente diferente es crear su fórmula a partir de una cadena. En la página de ayuda de formula
, encontrará el siguiente ejemplo:
## Create a formula for a model with a large number of variables:
xnam <- paste("x", 1:25, sep="")
fmla <- as.formula(paste("y ~ ", paste(xnam, collapse= "+")))
Luego, si observas la fórmula generada, obtendrás:
R> fmla
y ~ x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 +
x12 + x13 + x14 + x15 + x16 + x17 + x18 + x19 + x20 + x21 +
x22 + x23 + x24 + x25
Una extensión del método de Juba es usar reformulate
, una función que está explícitamente diseñada para tal tarea.
## Create a formula for a model with a large number of variables:
xnam <- paste("x", 1:25, sep="")
reformulate(xnam, "y")
y ~ x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 +
x12 + x13 + x14 + x15 + x16 + x17 + x18 + x19 + x20 + x21 +
x22 + x23 + x24 + x25
Para el ejemplo en el OP, la solución más fácil aquí sería
# add y variable to data.frame d
d <- cbind(y, d)
reformulate(names(d)[-1], names(d[1]))
y ~ x1 + x2 + x3
o
mod <- lm(reformulate(names(d)[-1], names(d[1])), data=d)
Tenga en cuenta que agregar la variable dependiente a data.frame en d <- cbind(y, d)
es preferible no solo porque permite el uso de reformulate
, sino también porque permite el uso futuro del objeto lm
en funciones como predict
.