如何用gratia::draw()绘制HGAM中独立于全局平滑的偏效应图?
在含全局平滑的HGAM模型中用gratia::draw()绘制独立个体偏效应图
要在包含全局平滑的HGAM模型中同时展示全局趋势和各Lake的完整个体趋势(全局+个体偏差),直接用gratia::draw()默认输出做不到——因为它只会单独展示每个平滑项的偏效应(全局平滑是单独一条,个体平滑是相对于全局的偏差)。但可以通过提取平滑项估计值并手动合并的方式,实现类似draw()风格的组合图,同时满足你在单个模型中展示两种趋势的需求。
具体步骤与代码示例
假设你已经拟合了目标模型:
library(mgcv) library(gratia) library(ggplot2) # 你的含全局平滑的HGAM模型 hgam_gi <- gam(Depth~Lake+s(OrdDay,bs="cc")+s(OrdDay,by=Lake,bs='cc')+s(Lake,bs="re"),data=df,family=nb)
- 提取平滑项估计值
分别提取全局平滑和各Lake的个体偏差平滑的结果:
# 提取全局平滑s(OrdDay)的估计与标准误 global_smooth <- smooth_estimates(hgam_gi, smooth = "s(OrdDay)") # 提取每个Lake相对于全局的偏差平滑s(OrdDay):Lake的估计与标准误 individual_deviations <- smooth_estimates(hgam_gi, smooth = "s(OrdDay):Lake")
- 计算各Lake的完整个体趋势
将全局平滑的估计值与对应Lake的偏差相加,得到每个Lake的完整平滑趋势,并合并标准误:
full_individual_trends <- individual_deviations %>% left_join(global_smooth, by = "OrdDay", suffix = c("_dev", "_global")) %>% mutate( fitted = est_dev + est_global, # 全局+个体偏差=完整个体趋势 se_fitted = sqrt(se_dev^2 + se_global^2) # 合并标准误 )
- 绘制组合偏效应图
用ggplot2(gratia底层依赖)绘制全局趋势+各Lake完整个体趋势,风格贴近draw()的简约感:
ggplot() + # 绘制全局平滑(加粗黑色线+置信区间) geom_line(data = global_smooth, aes(x = OrdDay, y = est), color = "black", linewidth = 1.2) + geom_ribbon(data = global_smooth, aes(x = OrdDay, ymin = est - 1.96*se, ymax = est + 1.96*se), alpha = 0.2, fill = "black") + # 绘制各Lake的完整个体趋势(彩色线+置信区间) geom_line(data = full_individual_trends, aes(x = OrdDay, y = fitted, color = Lake)) + geom_ribbon(data = full_individual_trends, aes(x = OrdDay, ymin = fitted - 1.96*se_fitted, ymax = fitted + 1.96*se_fitted, fill = Lake), alpha = 0.1) + # 调整标签与主题 labs(x = "Ordinal Day", y = "Partial Effect (Depth)", title = "Global Smooth + Individual Lake Trends from HGAM") + theme_minimal()
补充说明
- 如果你需要包含模型中
s(Lake, bs="re")的随机效应,可以在计算时额外提取随机效应的估计值并加入到fitted中,但通常偏效应图聚焦于平滑项的趋势,随机效应更多是捕捉组间的固定差异。 - 这种方法本质是基于平滑项的偏效应计算,和
predict.gam()输出的完整模型预测不同——后者会包含Lake固定效应、随机效应等所有项,而这里只展示平滑部分的趋势,更符合你“偏效应图”的需求。
内容的提问来源于stack exchange,提问作者David Smith
相关产品推荐
相关产品推荐

