在嵌套列表中为每个记录绘制回归线

时间:2019-04-05 03:23:12

标签: r ggplot2 nested tidyverse purrr

我有一个示例,该示例将数据嵌套到列表中,将线性模型添加到列表中的每个小标题,将回归系数添加到列表中的每个记录,并将2个不同的ggplot对象添加到列表中的每个记录。我想在每条记录的单独图上绘制回归线。我可以让geom_smooth精确地执行我要执行的操作,但是geom_abline似乎为列表中的每个记录添加了一个回归,每个图一个(我的示例有3条记录,因此每个图上有3行,而不是每个图上都需要一行记录。

library(tidyverse)
library(purrr)
library(broom)
library(ggplot2)

iris_species <- iris %>%  
  group_by(Species) %>%  
  nest()

# build model functions
model <- function(iris) {
  lm(Sepal.Length ~ Sepal.Width, data = iris)
}

# map models to the tibble
iris_species <- iris_species %>% 
  mutate(model = map(data, model))

iris_species # look at the structure

# add glance and tidy results to list
iris_species <- iris_species %>% 
  mutate(t = map(model, tidy)
         )

# unnest tidy list
iris_species_g <- iris_species %>% 
  unnest(t) %>% 
  select(Species, term, estimate) %>% 
  spread(key = term, value = estimate) %>%
  select(Species, `(Intercept)`, Sepal.Width) 

# pain down a list for species and data
iris_species_list <- iris_species %>% 
  select(Species, data, model)

# join  
iris_species_coeffs <- left_join(iris_species_list, iris_species_g, by = 'Species')

# add figures to list
iris_species_figs <- iris_species_coeffs %>% 
  mutate(plot1 = map(data, ~ ggplot(., aes(x = Sepal.Width, y = Sepal.Length)) +
                       geom_point() + 
                       geom_smooth(se = TRUE, size = 1, color = 'grey')
                     ) 
         ) 

iris_species_figs <- iris_species_figs %>% 
  mutate(plot2 = map(data, ~ ggplot(., aes(x = Sepal.Width, y = Sepal.Length)) +
                      geom_point() +
                      geom_abline(intercept = `(Intercept)`, slope = Sepal.Width, color = 'blue')
                    )
         ) 

iris_species_figs

# make figures
iris_species_figs$plot1 # works as expected

iris_species_figs$plot2 # does not

这是上面代码的最终产品:

# A tibble: 3 x 7
  Species    data              model    `(Intercept)` Sepal.Width plot1    plot2   
  <fct>      <list>            <list>           <dbl>       <dbl> <list>   <list>  
1 setosa     <tibble [50 × 4]> <S3: lm>          2.64       0.690 <S3: gg> <S3: gg>
2 versicolor <tibble [50 × 4]> <S3: lm>          3.54       0.865 <S3: gg> <S3: gg>
3 virginica  <tibble [50 × 4]> <S3: lm>          3.91       0.902 <S3: gg> <S3: gg>

运行最后两行显示了此问题。 plot1中的geom_smooth代码使用每个记录中的数据为每个记录创建1个图形,并将平滑线应用于每个图形。但是,plot2中的goem_abline不会。它似乎在三个图的每一个上绘制了全部3条线(每条记录中的一条)。关于如何使goem_abline表现得像geom_smooth的任何建议都将得到广泛认可。

1 个答案:

答案 0 :(得分:2)

您用于map的{​​{1}}函数仅映射plot 2,对于截距和斜率,它看到3个元素的向量。这就是为什么您在每个图中看到3条线的原因。

您必须使用data才能pmap用于每个绘图的所有信息/列。

尝试一下:

map