我正在尝试找出一种咕噜咕噜的方法,以迭代映射数据框列表中的列以适合单变量 GLM。 使用map2
,第一个元素.x
将是三个 pred 列,第二个元素.y
将是数据框的列表(反之亦然(。map2
似乎能够做到这一点,但我认识到我需要先越过 .x 和 .y 元素,所以我首先使用tidyr::crossing
来执行此操作。从这里开始,我不确定如何正确引用要在数据框中选择的列。示例代码如下:
#Sample data
set.seed(100)
test_df <- tibble(pred1 = sample(40:80, size = 1000, replace = TRUE),
pred2 = sample(40:80, size = 1000, replace = TRUE),
pred3 = sample(40:80, size = 1000, replace = TRUE),
resp = sample(100:200, size = 1000, replace = TRUE),
group = sample(c('a','b','c'), size = 1000, replace = TRUE))
#Split into list
test_ls <- test_df %>%
group_by(group) %>%
{df_groups <<- .} %>%
group_split()
#Obtain keys and name list elements
group_keys <- df_groups %>%
group_keys() %>%
pull()
test_ls <- test_ls %>% setNames(nm = group_keys)
#Cross all combinations of pred columns and list element names
preds <- c('pred1','pred2','pred3')
map_keys <- crossing(preds, group_keys)
#.y = list of data frames; iterate over data frames
#.x = three pred columns; iterate over columns
#Use purrr to fit glm of each .x columns within each of .y dfs
#Example structure - does not work
map2(.x, .y, .f = ~glm(resp ~ .x, data = .y))
#Workaround that does work
lapply(test_ls, function(x) {
x %>%
select(pred1, pred2, pred3) %>%
map(.f = ~glm(resp ~ .x, data = x))
})
我缺少一些东西,我似乎无法弄清楚。我在几种方法中遇到了各种错误,但我认为归结为没有正确引用.y
数据框中的.x
列。我的方法似乎没有认识到.x
是.y
中的一列。解决方法可以解决问题,但我宁愿避免同时使用lapply
和map
.
我的建议是在拟合模型之前不要拆分数据,因为您正在考虑原始数据集中已经直接可用的变量的所有可能组合。相反,请考虑将原始数据框转换为"长"格式,然后按必要的变量进行分组:
test_df %>% gather( pred, value, pred1:pred3 ) %>%
nest( -c(group, pred) ) %>%
mutate( models = map(data, ~glm(resp ~ value, data=.x)) )
# # A tibble: 9 x 4
# group pred data models
# <chr> <chr> <list> <list>
# 1 b pred1 <tibble [340 x 2]> <glm>
# 2 a pred1 <tibble [317 x 2]> <glm>
# 3 c pred1 <tibble [343 x 2]> <glm>
# 4 b pred2 <tibble [340 x 2]> <glm>
# 5 a pred2 <tibble [317 x 2]> <glm>
# 6 c pred2 <tibble [343 x 2]> <glm>
# 7 b pred3 <tibble [340 x 2]> <glm>
# 8 a pred3 <tibble [317 x 2]> <glm>
# 9 c pred3 <tibble [343 x 2]> <glm>
这大大简化了您的代码,如果您仍然需要在列表中使用这些模型,您现在可以拆分结果。