You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何无需逐个构建mgcv::gam模型,获取ggplot2中geom_smooth(gam)每条拟合线的调整R²?

解决思路

1. 分组批量拟合自动处理(最推荐)

既然你是按分组生成多条GAM拟合线,完全不用手动逐个敲model1 <- gam(...)这种重复代码,用dplyr的分组映射工具就能自动遍历每个分组、拟合模型并提取统计量。

举个具体的例子,假设你的数据框df包含响应变量y、自变量x1和分组变量group:

library(tidyverse)
library(mgcv)

# 批量拟合GAM并计算调整R²
group_adj_r2 <- df %>%
  group_by(group) %>%
  group_map(~ {
    # 对当前分组拟合GAM模型
    gam_mod <- gam(y ~ s(x1), data = .x)
    # 获取基础R²和GAM的有效自由度(不能用普通线性模型的参数个数)
    base_r2 <- summary(gam_mod)$r.sq
    n <- nrow(.x)
    total_edf <- sum(summary(gam_mod)$edf)
    # 计算适配GAM的调整R²
    adj_r2 <- 1 - (1 - base_r2) * (n - 1) / (n - total_edf - 1)
    # 返回当前分组的结果
    tibble(group = .y$group, adj_r_squared = adj_r2)
  }) %>%
  bind_rows()

跑完这段代码就能得到每个分组对应的调整R平方,就算有几十上百个分组也不用手动重复操作。如果你的GAM公式更复杂(比如加多个光滑项或协变量),直接修改gam()里的公式即可,所有分组会自动套用。

2. 结合broom包简化统计量提取

要是想更优雅地整理模型结果,可以搭配broom包,它能把模型输出转换成整洁的数据框,让统计量提取更顺畅:

library(broom)

gam_stats <- df %>%
  group_by(group) %>%
  group_map(~ {
    gam_mod <- gam(y ~ s(x1), data = .x)
    # 用glance提取基础模型统计量(含R²、AIC等)
    mod_glance <- glance(gam_mod)
    # 计算调整R²
    n <- nrow(.x)
    total_edf <- sum(summary(gam_mod)$edf)
    adj_r2 <- 1 - (1 - mod_glance$r.squared) * (n - 1) / (n - total_edf - 1)
    # 合并结果并补充分组信息
    mod_glance %>% mutate(group = .y$group, adj_r_squared = adj_r2)
  }) %>%
  bind_rows()

除了调整R平方,glance还会返回AIC、BIC等其他常用统计量,需要的话可以直接取用。

3. 从已生成的ggplot对象提取?(不推荐)

如果你已经用ggplot2的geom_smooth(method = "gam")画出了图,理论上可以通过ggplot_build()提取图层的计算数据,但这里面只有拟合值,没有完整的GAM模型对象,没法直接计算调整R平方。所以这种方法远不如直接批量拟合模型靠谱——毕竟ggplot的核心是绘图,不是保存模型参数。

最后提醒一句:GAM的调整R平方计算必须用有效自由度(edf),不能套用普通线性模型的调整R平方公式,上面的代码已经适配了这一点,可以放心用。

内容的提问来源于stack exchange,提问作者George

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 04:04:39