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

时间:2017-10-05 19:23:54

标签: r tidyverse purrr

我目前正在阅读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提取相应模型的系数。然而,在这个过程中,我丢失了所使用的种子的信息,因此失去了它所引用的数据集的链接,这迫使我做了丑陋的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
    )
  )

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

1 个答案:

答案 0 :(得分:3)

由于您添加了种子列,因此通常使用一个大型data.frame而不是data.frames列表更容易使用它。所以你可以做到

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代码