我试图编写一个遍历因子每个级别的函数(或使用purrr::map()
),并为因子等于该因子的数据子集拟合一个lm()
模型级别。
要使用mtcars
做一个简单的可重现示例,只需说我想为每个lm
的值使用不同的mtcars$gear
模型。我首先将其作为一个因素,因为我的真正问题涉及通过一个因素进行迭代:
library(tidyverse)
mtcars <- mtcars %>%
mutate(factor_gear = factor(gear))
我希望该函数适合factor_gear
的每个级别。级别通过以下方式给出:
levels(mtcars$factor_gear)
即
[1] "3" "4" "5"
所以我要寻找的输出将是:
fit1 <- lm(mpg ~ cyl, data = mtcars %>% filter(factor_gear=="3"))
fit2 <- lm(mpg ~ cyl, data = mtcars %>% filter(factor_gear=="4"))
fit3 <- lm(mpg ~ cyl, data = mtcars %>% filter(factor_gear=="5"))
fits <- list(fit1, fit2, fit3)
我已经开始使用该功能,但无法使其正常工作。
我认为函数应该:
fit_each_level <- function(factor_variable) {
# trying to: 1. get every level of of the factor into a vector
factor_levels <- levels(df_cars$factor_variable)
# trying to: 2. run an lm model for each level.
for i in factor_levels {
fit <- mtcars %>% filter(factor_variable==i [# every value of segment_levels]) %>%
lm(mpg ~ cyl, data = . )
}
}
fit_each_level(factor_gear)
如果该功能运行良好,我最终将能够在另一个因素上做到这一点,例如:
mtcars <- mtcars %>%
mutate(factor_carb = factor(carb))
fit_each_level(factor_carb)
答案 0 :(得分:3)
您可以nest
数据框,并使用map
为每个lm
应用factor_gear
。
library(dplyr)
mtcars %>%
group_by(factor_gear) %>%
tidyr::nest() %>%
mutate(model = map(data, ~lm(mpg ~ cyl, data = .x)))
# factor_gear data model
# <fct> <list> <list>
#1 4 <tibble [12 × 11]> <lm>
#2 3 <tibble [15 × 11]> <lm>
#3 5 <tibble [5 × 11]> <lm>
在新的dplyr
中,您可以使用cur_data
来引用组中的当前数据,从而无需使用nest
和map
。
mtcars %>%
group_by(factor_gear) %>%
summarise(model = list(lm(mpg ~ cyl, data = cur_data())))
答案 1 :(得分:1)
确保您具有最新版本的dplyr(1.0.0)。然后您可以使用:
model_coefs <- function(formula, data) {
coefs <- lm(formula, data)$coefficients
data.frame(coef = names(coefs), value = coefs)
}
mtcars %>%
dplyr::mutate(factor_gear = factor(gear)) %>%
dplyr::nest_by(factor_gear) %>%
dplyr::summarise(model_coefs(mpg ~ cyl, data)) %>%
tidyr::pivot_wider(names_from = coef, values_from = value)
# A tibble: 3 x 3
# Groups: factor_gear [3]
factor_gear `(Intercept)` cyl
<fct> <dbl> <dbl>
1 3 29.8 -1.83
2 4 41.3 -3.59
3 5 40.6 -3.2