R语言含交互项泊松GLM如何计算主效应Cohen's d
R中泊松GLM模型主效应Cohen's d效应量计算方案
问题描述
需要计算构建的泊松GLM模型各主效应对应的Cohen's d效应量,用于比较不同预测变量对因变量RA的效应大小,支撑Exp对RA的效应大于LastExp这类结论。
当前已完成的工作:
- 构建示例数据集的R代码:
RA <- c(40, 32, 41, 9, 27, 31, 29, 28, 48, 5, 18, 5, 3, 31, 31) Sex <- c('M', 'M', 'M', 'M', 'F', 'M', 'F', 'M', 'F', 'F', 'F', 'M', 'F', 'F', 'F') Mass <- c(10.9535, 4.3235, 9.2485, 4.8235, 6.896, 8.2075, 9.281, 0.734, 9.603, 0.973, 10.3435, 0.9505, 7.384, 6.935, 8.936) Exp <- c('Single', 'Mixed', 'Single','Double','Single','Single','Single','Double','Single','Mixed','Double','Mixed','Mixed','Single','Single') LastExp <- c('W','L','L','L','W','L','W','L','W','W','W','L','L','L','L') # 补充数据框组装步骤,原代码缺失该步会导致模型拟合报错 df <- data.frame(RA, Sex, Mass, Exp, LastExp)
- 已拟合的泊松GLM模型代码:
RAmodel <- glm(RA~Sex*Exp*LastExp+Mass, family=poisson(), data = df)
- 已实现全分组水平两两比较的Cohen's d计算,基于
emmeans包实现,代码如下:
library(emmeans) emRA <- emmeans(RAmodel, ~Sex*Exp*LastExp) eff_size(emRA, sigma = sigma(RAmodel), edf=31)
当前待解决的问题:
- 需要输出模型主效应对应的Cohen's d结果,输出格式与
car::Anova(RAmodel)返回结果类似,结果中附带各主效应的Cohen's d值 - 之前尝试使用
effsize包实现需求,但模型包含三因素交互项、非数值型分类变量,计算无法正常运行
注:若示例代码因数据集样本量限制无法正常运行,可自行扩充样本后复现。
解决方案
含交互项、分类协变量的GLM模型主效应效应量不要直接基于原始分组数据计算,需基于模型估计的调整后边际均值计算,逻辑和已实现的两两比较效应量计算完全一致,只需通过emmeans的joint=TRUE参数计算因子整体效应,最后和Anova结果合并即可得到需要的输出格式。
完整可运行代码如下:
# 加载依赖包 library(emmeans) library(car) library(dplyr) # 1. 获取III型方差分析表(适配带交互项的模型,和后续效应量计算逻辑匹配) anova_res <- as.data.frame(car::Anova(RAmodel, type = 3)) anova_res$term <- rownames(anova_res) # 2. 初始化效应量计算参数 mod_sigma <- sigma(RAmodel) # 模型残差标准差,和之前两两比较用的sigma保持一致 mod_edf <- df.residual(RAmodel) # 自动读取模型残差自由度,无需硬编码数值 model_terms <- c("Sex", "Exp", "LastExp", "Mass", "Sex:Exp", "Sex:LastExp", "Exp:LastExp", "Sex:Exp:LastExp") # 列出模型中所有项,包含主效应和交互项 # 3. 循环计算每个项的整体Cohen's d d_res <- data.frame( term = model_terms, cohens_d = NA_real_ ) for(i in seq_along(model_terms)){ # 对当前项估计调整后边际均值,自动控制其他变量为平均水平 em_i <- emmeans(RAmodel, as.formula(paste0("~", model_terms[i]))) # joint=TRUE 针对多水平因子/交互项计算整体效应量,而非输出两两比较结果 eff_i <- eff_size(em_i, sigma = mod_sigma, edf = mod_edf, joint = TRUE) d_res$cohens_d[i] <- as.numeric(eff_i$effect.size) } # 4. 合并结果,得到和car::Anova格式一致、附带Cohen's d的完整结果 final_res <- anova_res %>% left_join(d_res, by = "term") %>% select(term, Chisq, Df, `Pr(>Chisq)`, cohens_d) # 5. 仅保留主效应结果(筛掉含冒号的交互项) main_eff_res <- final_res %>% filter(!grepl(":", term)) # 打印查看结果 print(main_eff_res)
结果说明
- 输出的
main_eff_res和car::Anova输出结构完全对齐,包含每个主效应的卡方值、自由度、p值,最后一列是对应主效应的Cohen's d值 - 该Cohen's d是控制了其他协变量、交互项影响后的调整后效应量,不存在混淆偏差,可直接比较数值大小支撑「Exp对RA的效应大于LastExp」这类结论
- 多水平分类变量(如本例中Exp有3个水平)的Cohen's d为因子整体效应量,代表该因子所能解释的标准化组间差异大小,和两两组间比较的d值解释略有差异,报告时注意说明即可
内容的提问来源于stack exchange,提问作者Mac
相关产品推荐
相关产品推荐

