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

如何为Month2分组应用geom_smooth拟合GAM样条曲线?

解决ggplot按分组拟合GAM样条曲线的问题

数据集结构

> str(env)
tibble [1,363 × 15] (S3: tbl_df/tbl/data.frame)
 $ use_for_analysis: chr [1:1363] "Standard" "Standard" "Standard" "Standard" ...
 $ Date            : POSIXct[1:1363], format: "2011-01-07" "2011-01-07" "2011-01-07" ...
 $ CYR             : Factor w/ 18 levels "2005","2006",..: 7 7 7 5 7 7 7 7 7 5 ...
 $ Season          : Factor w/ 2 levels "DRY","WET": 1 1 1 1 1 1 1 1 1 1 ...
 $ Month           : num [1:1363] 1 1 1 1 1 1 1 1 1 1 ...
 $ Time            : POSIXct[1:1363], format: "1899-12-31 10:05:00" "1899-12-31 10:38:00" "1899-12-31 10:55:00" ...
 $ time2           : POSIXct[1:1363], format: "2022-12-01 10:05:00" "2022-12-01 10:38:00" "2022-12-01 10:55:00" ...
 $ DT              : POSIXct[1:1363], format: "2011-01-07 10:05:00" "2011-01-07 10:38:00" "2011-01-07 10:55:00" ...
 $ Site            : Factor w/ 47 levels "1","2","3","4",..: 46 44 43 22 45 47 42 33 34 19 ...
 $ temp            : num [1:1363] 17.6 18.4 18.6 18.8 18.8 ...
 $ sal             : num [1:1363] 31.2 30.3 29.9 18.5 31.3 ...
 $ DO              : num [1:1363] 6.12 6.65 6.29 6.56 7.25 ...
 $ water_depth     : num [1:1363] 39 42 58 36 58 70 68 71 40 67 ...
 $ sed_depth       : num [1:1363] 31 143 89 28 111 31 123 29 42 2 ...
 $ Month2          : Factor w/ 8 levels "Jan","Feb","Mar",..: 1 1 1 1 1 1 1 1 1 1 ...

问题场景

已通过ggplot绘制按Month2分组着色、CYR分面的temp随time2的散点图,尝试用geom_smooth(method='gam')为每个Month2分组拟合GAM样条曲线,但原代码无法实现,核心问题是geom_smooth的公式错误:

ggplot(env, aes(x=time2, y=temp, color = Month2)) + 
  geom_point(alpha = 0.2) + 
  geom_smooth(method='gam', formula = y ~ splines::ns(x,2) + b, se=FALSE) + # 此处公式中的b为无效变量
  facet_wrap(~CYR)

解决方案

核心问题说明

原公式中的b没有对应数据集中的实际变量,且未正确利用ggplot的分组逻辑。要实现每个Month2分组单独拟合曲线,可通过以下两种方法调整:


方法1:利用ggplot自动分组(推荐)

因为aes中已设置color=Month2,ggplot会自动按该变量分组拟合曲线,只需将公式改为GAM适配的平滑项格式。优先使用mgcv包的s()函数(GAM标准平滑项),需先加载mgcv包:

library(mgcv)

ggplot(env, aes(x=time2, y=temp, color = Month2)) + 
  geom_point(alpha = 0.2) + 
  geom_smooth(method = 'gam', formula = y ~ s(x, k=2), se = FALSE) + # s(x)为mgcv平滑项,k指定自由度
  facet_wrap(~CYR)

若坚持使用splines::ns,需明确结合分组变量构建交互项:

ggplot(env, aes(x=time2, y=temp, color = Month2)) + 
  geom_point(alpha = 0.2) + 
  geom_smooth(method = 'gam', formula = y ~ splines::ns(x, 2) * Month2, se = FALSE) +
  facet_wrap(~CYR)

方法2:显式指定分组

若自动分组未生效,可在geom_smooth的aes中额外指定group=Month2,确保按分组拟合:

library(mgcv)

ggplot(env, aes(x=time2, y=temp, color = Month2)) + 
  geom_point(alpha = 0.2) + 
  geom_smooth(aes(group=Month2), method='gam', formula = y ~ s(x, k=2), se=FALSE) +
  facet_wrap(~CYR)

关键提示

  • 使用method='gam'时,mgcv包的s()平滑项比splines::ns更适配GAM模型,是官方推荐用法。
  • 无需在公式中额外写分组变量,color=Month2或group=Month2已让ggplot为每个分组单独拟合曲线。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 15:00:45