首页 > 解决方案 > 如何在 geom_smooth() 中强制执行公共斜率?

问题描述

我有一个数据集,类似于tb下面生成的:

x = seq(0, 10, by=.4)
y1 = x + rnorm(x)
y2 = .25 + 1.25*x + rnorm(x)
tb = bind_rows(tibble(x=x, y=y1, z=F), tibble(x=x, y=y2, z=T))

请注意,这z是一个指示变量。我在 R 中计算了线性回归:

summary(lm(y ~ x + z, data=tb))

导致

Call:
lm(formula = y ~ x + z, data = tb)
Residuals:
     Min       1Q   Median       3Q      Max 
-1.84417 -0.79490 -0.02323  0.64194  2.37092 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept)  -0.5971     0.2951  -2.024   0.0485 *  
x             1.1068     0.0450  24.597  < 2e-16 ***
zTRUE         1.6958     0.2700   6.281 8.62e-08 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.9735 on 49 degrees of freedom
Multiple R-squared:  0.9293,    Adjusted R-squared:  0.9265 
F-statistic: 322.2 on 2 and 49 DF,  p-value: < 2.2e-16

现在我想绘制数据和回归线。但是,geom_smooth()将具有不同指标值的两个子集视为完全独立的数据集,并绘制两条具有不同斜率的回归线:

错误的线性回归

我真正想要的是这样的:

正确的线性回归

正如我的线性模型所暗示的,两条线是平行的。

我尝试在以下位置明确指定公式geom_smooth()

tb %>%
  ggplot(aes(x, y, colour=z, z=z)) + 
  geom_point() +
  geom_smooth(
    method="lm",
    formula = y ~ x + z
  )

但我收到警告:

警告消息:计算失败stat_smooth():找不到对象“z”

并且没有绘制回归线。

标签: rggplot2

解决方案


这个解决方案与成熟的统计软件所期望的简单和优雅相去甚远,但它确实有效:

lm1 = lm(y ~ x + z, data=tb)
tbPred = predict(lm1, newdata=tibble(x=x, z=F), se.fit=T)
tbLine = tibble(x=x, y=tbPred$fit, z=F)
tbBand = tibble(
  x=c(x, rev(x)),
  y=c(tbPred$fit - 1.96*tbPred$se.fit, rev(tbPred$fit + 1.96*tbPred$se.fit)),
  z=F
)
tbPred = predict(lm1, newdata=tibble(x=x, z=T), se.fit=T)
tbLine = bind_rows(tbLine, tibble(x=x, y=tbPred$fit, z=T))
tbBand = bind_rows(tbBand, tibble(
  x=c(x, rev(x)),
  y=c(tbPred$fit - 1.96*tbPred$se.fit, rev(tbPred$fit + 1.96*tbPred$se.fit)),
  z=T
))
tb %>%
  ggplot(aes(x, y, colour=z, fill=z)) +
  geom_point() +
  geom_line(data=tbLine, size=1.25) +
  geom_polygon(data=tbBand, colour=NA, alpha=.333)

它产生:

正确的线性回归图


推荐阅读