使用emmeans对GAM的arcsin变换结果做逆变换失败求助
问题:GAM模型中使用emmeans进行arcsin变换逆转换失败
我正在构建响应变量为百分比(0-100)的GAM模型,为优化拟合效果使用了arcsin变换(asin(sqrt(myvariable/100)))。目前我希望在原始尺度下评估解释因子变量各水平间的对比,因此尝试使用emmeans工具,并按照相关步骤设置了emmeans可识别的变换对象:
tran <- make.tran("asin.sqrt", 100)
该变换对象在线性模型中可正常工作:
warp.t <- with(tran, lm(linkfun(breaks)~wool*tension, warpbreaks)) emmeans(warp.t, ~wool|tension, type="response")
能成功输出逆变换后的结果,但将其应用到GAM模型时,无论是直接调用emmeans还是使用regrid(),均出现错误:
dat <- data.frame("x" = rep(1:3, times=12), "y" = rep(4:6, times=12), "z" = runif(36, 0, 100), "m" = rep(1:12, times=3)) gam.t <- with(tran, gam(linkfun(z) ~ x * y + s(m), data=dat)) emmeans(gam.t, ~x|y, type="response") # Error in linkinv(result[[cnm[1]]]) : could not find function "linkinv" # 或者用regrid() regrid(emmeans(gam.t, ~x|y), transform="response") # Error in flink$mu.eta(object@bhat[estble]) : # attempt to apply non-function
看起来emmeans在GAM模型中找不到预期位置的逆链接函数,请问能否为GAM指定该函数?emmeans是否不支持GAM?还是我的操作存在错误?
解决方案
问题根源在于:emmeans对GAM模型的元数据识别逻辑和线性模型不同,手动用with(tran, ...)变换响应变量构建的GAM模型,没有把变换信息嵌入到模型对象中,导致emmeans无法自动找到逆变换函数。emmeans完全支持GAM模型,只是需要正确传递变换规则。
方法1:手动给emmeans指定变换对象
可以直接在调用emmeans或regrid()时传入我们定义的tran对象,明确告知逆变换规则:
# 先获取变换尺度下的emmeans结果 emm <- emmeans(gam.t, ~x|y) # 应用逆变换回到原始百分比尺度 regrid(emm, tran = tran)
或者一步到位,在emmeans中直接指定:
emmeans(gam.t, ~x|y, type="response", tran=tran)
方法2:用GAM的family参数绑定变换(推荐)
更规范的方式是不要手动变换响应变量,而是利用gam函数的family参数来指定自定义变换,这样模型对象会自动携带变换/逆变换信息,后续工具都能直接识别:
# 创建arcsin.sqrt变换对应的family对象 asin_fam <- make.tran("asin.sqrt", 100) # 构建GAM时传入family参数,无需手动变换z gam.t <- gam(z ~ x * y + s(m), data=dat, family=asin_fam) # 直接调用emmeans,type="response"会自动应用逆变换 emmeans(gam.t, ~x|y, type="response")
这种方式的优势在于模型本身记录了变换规则,后续所有依赖模型元数据的操作(比如诊断、预测)都能自动适配原始尺度,避免手动传递变换对象的繁琐。
内容的提问来源于stack exchange,提问作者evelyn
相关产品推荐
相关产品推荐

