R中mgcv::gam报错:协变量组合数小于最大自由度问题排查
问题背景
我有两年的每日声学指数数据(共7994条观测,20个站点,分为恢复/未恢复处理组、低/高入侵组),想用mgcv::gam分析季节、年度趋势及恢复、入侵对声学指数的影响。之前用周平均数据分年度建模没问题,但合并两年数据用以下代码建模时反复报错:
knots<-list(DATE=c(0.5, 366.5)) ACI_daily<-mgcv::gam(ACI~ s(DATE, by=TRT, k=12, bs='cc')+ s(DATE, by=InvFac, k=12, bs='cc')+ s(Year, k=2)+ ti(DATE, Year, bs= c('cc','tp'), k=c(12,2))+ s(Site, k=10, bs='re'), data=Acoustic_Daily, family=Gamma(link='log'), method='REML', nthreads = c(4,1), knots=knots, select = TRUE )
触发的错误信息:
Error in smooth.construct.tp.smooth.spec(object, dk$data, dk$knots) : A term has fewer unique covariate combinations than specified maximum degrees of freedom
调整k值后,要么仍报错,要么出现警告:
In addition: Warning messages: 1: In te(..., k = k, bs = bs, m = m, d = d, fx = fx, np = np, xt = xt, : one or more supplied k too small - reset to default
已定位问题出在Year变量,想确认是否是站点随机效应(每年各10组配对站点)或仅两年数据的交互项导致的问题?
问题根源与解决办法
核心原因
问题确实出在仅两年数据的交互项以及Year相关的平滑项设置,和站点随机效应无直接关联:
s(Year, k=2)的问题:Year只有2个唯一值,tp样条配合select=TRUE时,模型尝试收缩该平滑项,但2个水平的变量没有足够变异空间支撑平滑结构,容易触发自由度不匹配错误。ti(DATE, Year, k=c(12,2))的问题:张量积交互中Year维度设置k=2,但Year仅2个水平,无法构建有效的tp样条平滑,直接导致“唯一协变量组合少于指定自由度”的错误。
具体调整方案
- 替换单独的Year平滑项:把
s(Year, k=2)改为分类变量factor(Year),直接估计两年的截距差异,更符合Year仅2个水平的实际情况。 - 替换DATE与Year的张量积交互:用
s(DATE, by=factor(Year), bs='cc', k=12)替代原ti项,通过分组平滑分别拟合两年的季节趋势,本质上实现DATE与Year的交互效应,适配Year水平少的场景。
调整后的模型代码:
knots<-list(DATE=c(0.5, 366.5)) ACI_daily<-mgcv::gam(ACI~ s(DATE, by=TRT, k=12, bs='cc')+ s(DATE, by=InvFac, k=12, bs='cc')+ factor(Year)+ s(DATE, by=factor(Year), bs='cc', k=12)+ s(Site, k=10, bs='re'), data=Acoustic_Daily, family=Gamma(link='log'), method='REML', nthreads = c(4,1), knots=knots, select = TRUE )
额外说明
如果坚持用张量积形式,只能将Year维度的k设为1,但此时Year退化为线性项,失去平滑意义,远不如分类变量交互直观。站点随机效应 s(Site, k=10, bs='re')设置合理,20个站点的场景下k=10符合随机效应的参数设置要求。
内容的提问来源于stack exchange,提问作者Gabrielle Ripa

