如何用ggplot在同一图中绘制病例数的简单与多重线性回归曲线?
嘿,我来帮你搞定这个ggplot的回归趋势绘图问题!首先先纠正一个小细节:你写的多重线性回归公式lm(case~ I(year +rain), data=data)其实不符合需求——I(year+rain)是把年份和降雨量相加作为单个变量,而我们要做的是同时纳入year和rain作为自变量,实现“经降雨量调整”的时间趋势,所以正确的公式应该是lm(case~ year + rain, data=data)哦。
接下来我会一步步带你用ggplot画出两条对比趋势线,核心思路是先拟合模型,生成包含预测值的数据集,再用ggplot的图层叠加实现:
第一步:拟合两个回归模型
先把你的原始数据和两个模型都准备好:
# 原始数据 data <- data.frame( x=c(1:12) , case=c(3,5,1,8,2,4,5,0,8,2,3,5) , rain=c(1,8,2,1,4,5,3,0,8,2,3,4) , country=c("A","A","A","A","B","B","B","B","C","C","C","C") , year=rep(seq(2000,2003,1),3) ) # 未调整的粗趋势模型 model_unadj <- lm(case ~ year, data = data) # 经降雨量调整的模型(正确公式) model_adj <- lm(case ~ year + rain, data = data)
第二步:生成用于绘图的预测数据集
ggplot是数据驱动的绘图工具,我们需要先算出两个模型在不同年份的拟合值,才能画出趋势线。对于调整后的模型,因为它同时包含year和rain,我们需要固定rain在一个参考水平(比如整体均值),这样画出的是控制降雨量为平均水平时,病例数随年份的趋势:
# 创建预测数据集:覆盖所有年份,rain取均值作为参考 pred_data <- expand.grid( year = unique(data$year), rain = mean(data$rain) ) # 计算两个模型的预测值 pred_data$unadj_pred <- predict(model_unadj, newdata = pred_data) pred_data$adj_pred <- predict(model_adj, newdata = pred_data)
第三步:用ggplot绘制对比图
现在我们可以把原始散点和两条趋势线叠加起来,还能给不同国家的点加上颜色区分,让图更清晰:
library(ggplot2) ggplot(data, aes(x = year, y = case)) + # 绘制原始病例数散点,按国家区分颜色 geom_point(aes(color = country), size = 3, alpha = 0.7) + # 绘制未调整的粗趋势线 geom_line(data = pred_data, aes(y = unadj_pred, color = "粗趋势(未调整)"), size = 1.2) + # 绘制经降雨量调整的趋势线(用虚线区分) geom_line(data = pred_data, aes(y = adj_pred, color = "经降雨量调整"), size = 1.2, linetype = "dashed") + # 自定义颜色和图例名称 scale_color_manual( name = "趋势/国家", values = c( "粗趋势(未调整)" = "darkblue", "经降雨量调整" = "darkred", "A" = "skyblue", "B" = "orange", "C" = "green" ) ) + # 添加标题和坐标轴标签 labs( x = "年份", y = "病例数", title = "2000-2003年病例数时间趋势对比", caption = "注:调整后趋势基于降雨量均值绘制" ) + # 用简洁的主题,让标题居中 theme_minimal() + theme(plot.title = element_text(hjust = 0.5))
为什么不用abline?
abline可以直接调用模型系数画直线,但它没法灵活调整调整后模型的参考条件(比如固定rain的水平),也很难和ggplot的图层系统完美兼容。用预测数据集的方式,你可以轻松修改rain的参考值(比如取中位数、分组均值),或者添加置信区间(只需要在predict()里加interval="confidence"即可),灵活性更高。
内容的提问来源于stack exchange,提问作者user3355655
相关产品推荐
相关产品推荐

