lmer模型自定义变换后如何将emmeans反变换回原始尺度
lmer自定义变换后emmeans反变换回原始尺度的实现方法
你之前的代码无法触发自动反变换,核心原因是emmeans的tran参数仅识别内置的标准变换名称(如"log"、"sqrt"、"logit"等),传入自定义变换后的变量名字符串时,程序无法匹配到对应的正反变换规则,会默认按无变换处理,因此输出结果停留在变换后的尺度。
按以下步骤操作即可正确实现反变换:
- 第一步:固定变换过程中用到的常量
你的变换用到了响应变量的中位数,这个值必须在变换阶段就固定存储,不能在反变换阶段重新计算,否则会因为样本子集变化导致偏移量不一致,结果完全失真。需要额外注意:你当前使用的变换包含abs()取绝对值操作,严格来说不可逆,会丢失原始值相对于中位数的偏移方向信息,如果需要保留方向,需要在变换阶段单独存储每个观测的偏移符号。# 固定变换用的中位数常量 med_v1 <- median(dataframe$Variable1) # 可选:如果需要保留偏移方向,提前存储符号 # dataframe$v1_sign <- sign(dataframe$Variable1 - med_v1) # 计算变换后的响应变量 dataframe$TransformVariable1 <- sqrt(abs(dataframe$Variable1 - med_v1)) # 拟合模型 fit <- lmer(TransformVariable1 ~ x + y + (1|z), data = dataframe) - 第二步:给参考网格传入自定义反变换规则
不要给tran传字符串,直接传入包含反变换函数的列表即可,emmeans会自动识别自定义变换规则。# 定义反变换函数:输入变换尺度的预测值,返回原始尺度值 custom_inv <- function(t) { # 基础反变换逻辑:开根号的逆是平方,加回固定的中位数偏移 raw_val <- t^2 + med_v1 # 如果需要加回方向,可在此处乘对应分组的平均符号,注意符号信息因abs操作已损失,需提前存储 return(raw_val) } # 构建参考网格,传入自定义变换 rg <- update( ref_grid(fit), tran = list( linkinv = custom_inv, mu.eta = function(t) 2*t, # 可选:反变换的导数,传入后可通过delta方法计算更准确的标准误和置信区间 name = "sqrt-median custom transform" ) ) - 第三步:正常计算边际均值即可自动反变换
此时使用type = "response"参数,输出结果就会自动映射回原始响应变量的尺度:fitemm <- as.data.frame(emmeans(rg, ~ x + y, type = "response"))
补充说明:如果没有传入
mu.eta参数,emmeans会默认用数值近似方法计算原始尺度的区间估计,结果可用但精度略低。
内容的提问来源于stack exchange,提问作者Ana Carolina
相关产品推荐
相关产品推荐

