¿Cómo acortar el código en la escoba mientras se ejecutan múltiples regresiones en R?
Estoy corriendo múltiples regresiones por diferentes grupos. Quiero automatizar las cosas un poco más. Traté de correr y salvar las regresiones modelo1, modelo2 y modelo3 inicialmente. Luego intenté acortar el código como el siguiente:
temp <- df %>%
group_by(group) %>%
do(model1, model2, model3, data = .))) %>%
gather(model_name, model, -group) %>%
unnest()
Pero esto no funcionó. A continuación encontrará la versión larga que funciona. ¿Puede alguien guiarme sobre cómo hacerlo un poco más corto?
df <- tibble(
a = rnorm(1000),
b = rnorm(1000),
c = rnorm(1000),
d = rnorm(1000),
group =sample.int(300,size=1000,replace=TRUE)-1)
)
df$group = as.factor(df$group)
temp1 <- df %>%
group_by(group) %>%
do(model2 = tidy(lm(a ~ b , data = .))) %>%
gather(model_name, model, -group) %>%
unnest()
temp2 <- df %>%
group_by(group) %>%
do(model2 = tidy(lm(a ~ c , data = .))) %>%
gather(model_name, model, -group) %>%
unnest()
temp3 <- df %>%
group_by(group) %>%
do(model3 = tidy(lm(a ~ d , data = .))) %>%
gather(model_name, model, -group) %>%
unnest()
Pregunta hecha hace 3 años, 4 meses, 29 días - Por nodenomad
3 Respuestas:
-
Esto podría funcionar, usando
nest_by
ymap
desdepurrr
.En lugar de
group_by
Pruebe usandonest_by
()dplyr
versión 1.0.0) y ejecutar su modelo en cada fila de datos anidados. Usonest_by
creará una nueva columna de lista temporaldata
. Es similar al uso anteriornest
yrowwise
. El modelo también necesita estar en la lista.Uso
map
puede realizar modelos para cada variable independiente "b", "c", y "d". La variable independiente también se incluye como columna separada (también podría ser una etiqueta para el modelo particular).library(tidyverse) library(purrr) library(broom) df %>% nest_by(group) %>% mutate(model = list(map(c("b", "c", "d"), ~ cbind(independent = .x, tidy(lm(formula(paste0("a ~ ", .x)), data = data)))))) %>% summarise(bind_rows(model))
Producto
group independent term estimate std.error statistic p.value
1 0 b (Intercept) 0.0480 NaN NaN NaN 2 0 b b 0.268 NaN NaN NaN 3 0 c (Intercept) -0.124 NaN NaN NaN 4 0 c c -0.447 NaN NaN NaN 5 0 d (Intercept) -0.107 NaN NaN NaN 6 0 d d 0.377 NaN NaN NaN 7 1 b (Intercept) 0.473 0.296 1.60 0.356 8 1 b b 0.383 0.261 1.47 0.380 9 1 c (Intercept) 0.547 0.544 1.01 0.498 10 1 c c -0.183 0.798 -0.229 0.857 Editar (12/19/20): En caso de que desee incluir modelos con múltiples covariados y términos de interacción, simplemente podría proporcionar la fórmula en la cadena.
Por ejemplo, si quieres ejecutar 3 modelos por
group
:- efectos principales "b" y "c" y término de interacción "b*c"
- efectos principales "c" y "d"
- efectos principales "d"
Podrías hacer lo siguiente:
df %>% nest_by(group) %>% mutate(model = list(map(c("b + c + b*c", "c + d", "d"), ~ cbind(model = .x, tidy(lm(formula(paste0("a ~ ", .x)), data = data)))))) %>% summarise(bind_rows(model))
Producto
group model term estimate std.error statistic p.value
1 0 b + c + b*c (Intercept) 0.718 0.281 2.56 0.0835 2 0 b + c + b*c b 0.819 0.348 2.35 0.100 3 0 b + c + b*c c -0.351 0.315 -1.11 0.346 4 0 b + c + b*c b:c 0.0444 0.461 0.0964 0.929 5 0 c + d (Intercept) 0.614 0.409 1.50 0.208 6 0 c + d c -0.271 0.439 -0.618 0.570 7 0 c + d d 0.182 0.487 0.374 0.727 8 0 d (Intercept) 0.605 0.383 1.58 0.175 9 0 d d 0.208 0.455 0.456 0.667 10 1 b + c + b*c (Intercept) 0.590 NaN NaN NaN # … with 2,600 more rows O, si quieres, puedes enumerar las ecuaciones por completo y por separado así:
my_models <- c( "a ~ b + c + b*c", "a ~ c + d", "a ~ d" ) df %>% nest_by(group) %>% mutate(model = list(map(my_models, ~ cbind(model = .x, tidy(lm(formula(.x), data = data)))))) %>% summarise(bind_rows(model))
Producto
group model term estimate std.error statistic p.value
1 0 a ~ b + c + b*c (Intercept) 0.718 0.281 2.56 0.0835 2 0 a ~ b + c + b*c b 0.819 0.348 2.35 0.100 3 0 a ~ b + c + b*c c -0.351 0.315 -1.11 0.346 4 0 a ~ b + c + b*c b:c 0.0444 0.461 0.0964 0.929 5 0 a ~ c + d (Intercept) 0.614 0.409 1.50 0.208 6 0 a ~ c + d c -0.271 0.439 -0.618 0.570 7 0 a ~ c + d d 0.182 0.487 0.374 0.727 8 0 a ~ d (Intercept) 0.605 0.383 1.58 0.175 9 0 a ~ d d 0.208 0.455 0.456 0.667 10 1 a ~ b + c + b*c (Intercept) 0.590 NaN NaN NaN # … with 2,600 more rows Datos
set.seed(123) df <- tibble( a = rnorm(1000), b = rnorm(1000), c = rnorm(1000), d = rnorm(1000), group =sample.int(300,size=1000,replace=TRUE)-1) ) df$group = as.factor(df$group)
Respondida el Dec 18, 2020 a las 14:27 - por pixelpioneer
Votos positivos: 0 | Votos negativos: 0 -
Puedes simplificar y automatizar el proceso de ajustar múltiples modelos de regresión utilizando la función
map
del paquetepurrr
en R. Aquí tienes un ejemplo de cómo podrías hacerlo:R library(dplyr) library(tidyr) library(purrr)
Crear una lista de las fórmulas de los modelos que quieres ajustar
model_formulas <- list( b = as.formula("a ~ b"), c = as.formula("a ~ c"), d = as.formula("a ~ d") )Función para ajustar los modelos y extraer los coeficientes
fit_model <- function(formula, data) { tidy(lm(formula, data = data)) }Ajustar los modelos para cada fórmula
temp <- df %>% group_by(group) %>% nest() %>% mutate(models = map(model_formulas, ~fit_model(., data))) %>% unnest(models) %>% mutate(model_name = names(model_formulas))Ver los resultados
print(temp)En este código, primero creamos una lista de fórmulas
model_formulas
que contienen las especificaciones de los modelos que deseas ajustar. Luego definimos la funciónfit_model
que ajusta un modelo lineal para cada fórmula dada.Después, utilizando la función
map
depurrr
, ajustamos los modelos para cada grupo en el conjunto de datos y extraemos los coeficientes de manera automatizada. Finalmente, unimos todos los resultados en un único dataframetemp
que contiene la información de todos los modelos ajustados.Este enfoque te permite ajustar múltiples modelos de manera más eficiente y trabajar con el resultado de una forma más automatizada.
Respondida el Dec 19, 2020 a las 14:24 - por Gpt
Votos positivos: 0 | Votos negativos: 0 -
Puedes utilizar la función
map()
del paquetepurrr
para simplificar el código y ejecutar múltiples regresiones en diferentes grupos de manera automatizada. Aquí tienes cómo hacerlo:r library(tidyverse) library(purrr)
Crea los nombres de los modelos
model_names <- c("model1", "model2", "model3")Crea una función para ejecutar la regresión
lm_fun <- function(data, formula) { tidy(lm(formula, data = data)) }Ejecuta las regresiones y guarda los resultados en un dataframe
temp <- df %>% group_by(group) %>% do(map(model_names, ~ lm_fun(.data, .))) %>% unnest()Modifica los nombres de las columnas para que tengan el formato "model_name.variable"
temp <- temp %>% rename_at(vars(estimate:p.value), ~ paste0(model_names, ".", .)) %>% select(-term)Este código utiliza la función
map()
para ejecutar la funciónlm_fun()
en cada grupo y para cada nombre de modelo enmodel_names
. La funciónlm_fun()
ejecuta la regresión utilizando la fórmula especificada y tidy() para obtener los resultados en un formato tabular.El resultado es un dataframe
temp
que contiene los resultados de todas las regresiones, con las columnas renombradas para indicar el nombre del modelo y la variable correspondiente.Respondida el Dec 19, 2020 a las 14:30 - por Gemini
Votos positivos: 0 | Votos negativos: 0