ggplot2中geom_smooth(lm)与predict()回归线不一致问题咨询
问题原因与解决方法
核心原因
你代码里的两个回归模型形式完全不同:
- 手动拟合的
mod <- lm(y ~ x + group, df)是包含x和group主效应的整体模型,假设两组数据的x斜率一致,仅截距存在差异(模型公式:y = β₀ + β₁x + β₂group)。 - 而
geom_smooth(method="lm", formula="y ~ x")因为全局映射中指定了col=factor(group),ggplot会自动按group分组,对每个组单独拟合仅包含x的简单线性回归(两组的斜率和截距都独立估计,公式分别为y = α₀ + α₁x和y = α₀' + α₁'x)。
模型假设不同,最终生成的回归线自然无法匹配。
修正方法
方法1:让geom_smooth使用与手动模型一致的公式
如果想让geom_smooth输出和predict()一致的线条,需要让它拟合包含group的模型,同时避免按group分组拟合:
ggplot(df, aes(x, y)) + geom_point(aes(col= factor(group))) + # 将颜色映射仅放在散点层 geom_smooth(method= "lm", formula= "y ~ x + group", aes(col= factor(group))) + geom_line(data=df_pred, mapping= aes(x, pred, col= factor(group)))
或者保留全局颜色映射,在geom_smooth中强制不分组:
ggplot(df, aes(x, y, col= factor(group))) + geom_point() + geom_smooth(method= "lm", formula= "y ~ x + group", group=1) + # group=1强制整体拟合 geom_line(data=df_pred, mapping= aes(x, pred, col= factor(group)))
方法2:手动拟合与geom_smooth一致的分组模型
如果希望手动预测值和geom_smooth的分组回归线匹配,需要按group分别拟合简单线性回归:
# 按group分组拟合模型 mods <- lapply(split(df, df$group), function(sub_df) lm(y ~ x, sub_df)) # 生成分组预测值 df_pred_list <- lapply(names(mods), function(g) { sub_new <- data.frame(x= seq(min(df$x), max(df$x), 1), group= as.integer(g)) sub_new$pred <- predict(mods[[g]], sub_new) sub_new }) df_pred <- do.call(rbind, df_pred_list) # 绘图 ggplot(df, aes(x, y, col= factor(group))) + geom_point() + geom_smooth(method= "lm", formula= "y ~ x") + geom_line(data=df_pred, mapping= aes(x, pred, col= factor(group)))
内容的提问来源于stack exchange,提问作者LulY
相关产品推荐
相关产品推荐

