如何使用 tidyverse 将线性模型拟合到多个随机生成的数据集

How to fit linear models to several randomly generated datasets using the tidyverse

我目前正在阅读 Hadley Wickham 的 R for Data Science,并在 23.2.1 中遇到了练习,处理线性模型的稳健性,这些线性模型与随机生成的数据集的平方差相匹配。

我尝试使用 tidyverse 包来实现这个。

generate_data <- function(seed){
  set.seed(seed)
  tibble(
    x = rep(1:10, each = 3),
    y = x * 1.5 + 6 + rt(length(x), df = 2),
    seed = as.character(seed)
  )
}
seeds <- 6:11
datasets <- seeds %>% 
  map(generate_data) 

这是关键。数据集存在于数据帧列表中,因此我使用了 map 函数,最后使用 coef 提取了各个模型的系数。然而,在这个过程中,我丢失了所用种子的信息,因此丢失了它所引用的数据集的 link,这迫使我做丑陋的 mutate(seed = as.character(seeds)) 事情。

model_parameters <- datasets %>%
  map(~ lm(y ~ x, data = .)) %>%
  map(coef)

model_parameters <- model_parameters %>% 
  map_df(bind_rows) %>% 
  mutate(seed = as.character(seeds))

将数据帧列表转换为单个数据帧以进行绘图:

datasets <- datasets %>% map_df(bind_rows)

ggplot(datasets,
       aes(x,y, col = seed)
       ) +
  geom_jitter(width = .1) +
  geom_abline(
    data = model_parameters,
    aes(
      intercept = `(Intercept)`, 
      slope = x,
      color = seed
    )
  )

我的解决方案似乎有些难看。有更自然的方法吗?

由于您添加了种子列,因此使用一个大的 data.frame 比 data.frame 的列表通常更容易。所以你可以做

library(tidyverse)
datasets <- seeds %>% 
  map_df(generate_data) 

然后在提取系数时,broom 包可以以一种整洁的方式提供帮助。例如

model_parameters <- datasets %>% group_by(seed) %>% 
  do(broom::tidy(lm(y~x, .))) %>% 
  select(seed, term, estimate) %>% 
  spread(term, estimate)

那么这些都可以直接进入你已经写好的ggplot代码