使用 dplyr、broom 和 ggplot 注释分组的线性模型

问题描述

我开始深入研究如何在 dplyr/ggplot 中可视化简单的统计分析。我通过绑定 broom::augment 来研究如何通过分组来获得线性模型以使其正常工作。

我有三个问题:

  1. 将拟合的摘要信息(r 平方、截距、p vals)按组关联回原始数据帧的优雅方式是什么(在这种情况下,组中的所有值都将相同)?
  2. 如何仅用一个值来注释每组的回归线以在图中显示 r 平方和曲线拟合)?特别是,如何获得正确的对齐方式/颜色,以便清楚哪个文本注释与哪个回归线匹配?
  3. 在我根据一些较旧的 SO 答案整理出如何进行分组分析后,我了解到 do 现在已被 across() 取代,但我很难弄清楚如何使用 do(fit_carb = augment(lm(drat ~ mpg,data = .))) 重写 across()
#// library and data prep
library(tidyverse)
library(broom)

data <- mtcars
data$carb <- as.factor(data$carb)

#// generate scatter plot
plot <- 
     ggplot() + 
     geom_point(data = data,aes(x = mpg,y = drat,color = carb)) 

#// use lm function to generate linear regression model
fit <- lm(formula = drat ~ mpg,data = data)

#// tie results back into dataframe
lm_data <- augment(fit)

#// add fitted points and line
plot +    
     ggtitle("scatter plot with fitted points and line") + 
     #// add geom_point and geom_line with lm_data
     geom_point(data = lm_data,y = .fitted),color = "red") +
     geom_line(data = lm_data,color = "red")


#// linear model by group

lm_data <- data %>%
     #// group by factor
     group_by(carb) %>%
     #// `.` notation means that object gets piped into that place
     do(fit_carb = augment(lm(drat ~ mpg,data = .))) %>% 
     #// unnest table by the augment results
     unnest(fit_carb)

#// add fitted points and line grouped by carb
plot +    
     ggtitle("scatter plot with fitted points and line") + 
     #// add geom_point and geom_line with lm_data
     geom_point(data = lm_data,y = .fitted,group = carb),group = carb,color = carb))

ungrouped

grouped

解决方法

您可以省略 do dplyr 动词而只使用 mutatesummarise。根据您的图表,您不喜欢 broom::glance 吗?

data %>%
  group_by(carb) %>%
  mutate(glance(lm(mpg ~ drat))) %>%
  dplyr::select(mpg:carb,adj.r.squared,p.value)
## A tibble: 32 x 13
## Groups:   carb [6]
#     mpg   cyl  disp    hp  drat    wt  qsec    vs    am  gear carb  adj.r.squared p.value
#   <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <fct>         <dbl>   <dbl>
# 1  21       6  160    110  3.9   2.62  16.5     0     1     4 4             0.539 0.00943
# 2  21       6  160    110  3.9   2.88  17.0     0     1     4 4             0.539 0.00943
# 3  22.8     4  108     93  3.85  2.32  18.6     1     1     4 1             0.643 0.0185 
# 4  21.4     6  258    110  3.08  3.22  19.4     1     0     3 1             0.643 0.0185 
# ...

至于绘图,我知道这不是您真正期望的,但是如果您的主要目的是绘图,在我看来,最简单的方法是利用 ggpubr::stat_regline_equation

library(ggpubr)
ggplot(data = data,aes(x = mpg,y = drat,color = carb)) + 
  ggtitle("Scatter plot with fitted points and line") + 
  geom_point() + 
  geom_smooth(method = "lm",se = FALSE) +
  stat_regline_equation(label.x = with(data,tapply(mpg,carb,quantile,.6)),label.y = with(data,tapply(drat,max) - 0.2),aes(label = ..adj.rr.label..),show.legend = FALSE) 

enter image description here

您可以使用 geom_smooth 的附加参数来调整回归。如果你需要等式,你可以做类似 label = paste(..eq.label..,..adj.rr.label..,sep = "~~~")

对于简单的情况,手动指定 label.xlabel.y 通常更容易,但对于更复杂的情况,您可以使用基数 R tapply 来动态计算位置。 position = 有一个 stat_regline_equation 参数,但我从来没有让它起作用。