R语言emmeans组内差异标记、可视化及cld报错问题求助
问题背景
使用R语言的logistic回归模型研究温度(因子,含20、23、26、29、32℃5个水平)和物种(因子,含HA、AP2个水平)对昆虫发育至1龄幼虫概率的影响,模型代码如下:
eggmodelA <- glm(cbind(No.hatched,No.eggs.added-No.hatched) ~ Temperature * Species, data=eggto1st.1, family = binomial(link="logit"))
似然比检验显示温度与物种的交互项显著,因此通过emmeans包进行组内两两比较:
Within.species<-emmeans(eggmodelA, specs = pairwise ~ Temperature|Species) Within.temperature<-emmeans(eggmodelA, specs = pairwise ~ Temperature|Species)
遇到以下问题:
- 如何在
emmeans$contrasts结果中添加字母标记,区分同一物种内发育概率无显著差异的温度水平? - 能否将上述差异标记添加至
emmip绘制的模型图中,同时添加每个温度下两物种是否存在显著差异的标识? - 使用
multcompView包的cld()函数时出现报错:
Error in UseMethod("cld") : no applicable method for 'cld' applied to an object of class "emmGrid"
解决方案
1. 解决cld()报错并生成组内差异字母标记
报错原因是**multcompView::cld()不支持直接处理emmGrid对象**,需使用emmeans包自带的cld()函数(该函数专门为emmGrid对象设计)。步骤如下:
# 确保加载emmeans包 library(emmeans) # 提取emmeans结果对象 emm_obj <- Within.species$emmeans # 生成字母标记:同一字母表示同一物种内温度组间差异不显著 cld_result <- cld(emm_obj, alpha = 0.05, letters = letters, adjust = "tukey") # 查看带字母标记的结果 print(cld_result)
输出结果中,.group列即为分组字母,同一物种内共享相同字母的温度水平无显著差异。
2. 在绘图中添加差异标记(组内字母+物种间显著性)
emmip的自定义扩展性有限,推荐使用ggplot2结合emmeans结果绘图,更灵活地添加标记:
2.1 绘制带组内温度差异字母的基础图
先将cld_result转换为数据框,再用ggplot2绘图:
library(ggplot2) # 将emmeans结果转换为数据框 emm_df <- as.data.frame(cld_result) # 绘制基础图+组内字母标记 ggplot(emm_df, aes(x = Temperature, y = prob, color = Species, group = Species)) + geom_point(size = 3) + # 添加95%置信区间 geom_errorbar(aes(ymin = asymp.LCL, ymax = asymp.UCL), width = 0.2) + # 添加字母标记,vjust调整垂直位置 geom_text(aes(label = .group), vjust = -1.5, size = 4) + labs( x = "Temperature", y = "Predicted probability of reaching 1st instar from egg (± 95% confidence intervals)", color = "Species" ) + theme_classic()
2.2 添加同一温度下物种间的显著性标识
方法1:手动添加星号标记
先筛选出物种间差异显著的温度,再在对应位置添加标记:
# 执行温度内的物种两两比较 Within_temp <- emmeans(eggmodelA, pairwise ~ Species|Temperature, type = "response") # 提取显著差异的温度及对应显著性等级 sig_comp <- as.data.frame(Within_temp$contrasts) |> mutate(signif = case_when( p.value < 0.001 ~ "***", p.value < 0.01 ~ "**", p.value < 0.05 ~ "*", TRUE ~ "" )) |> filter(signif != "") |> select(Temperature, signif) # 获取每个温度置信区间的最大值,用于放置标记 max_y <- emm_df |> group_by(Temperature) |> summarise(y_pos = max(asymp.UCL) + 0.06) |> left_join(sig_comp, by = "Temperature") # 绘制带两种标记的图 ggplot(emm_df, aes(x = Temperature, y = prob, color = Species, group = Species)) + geom_point(size = 3) + geom_errorbar(aes(ymin = asymp.LCL, ymax = asymp.UCL), width = 0.2) + geom_text(aes(label = .group), vjust = -1.5, size = 4) + # 添加物种间显著性标记 geom_text(data = max_y[!is.na(max_y$signif), ], aes(x = Temperature, y = y_pos, label = signif), size = 5, inherit.aes = FALSE) + labs( x = "Temperature", y = "Predicted probability of reaching 1st instar from egg (± 95% confidence intervals)", color = "Species" ) + theme_classic()
方法2:用ggsignif添加连线式标记(更美观)
使用ggsignif包自动添加物种间差异的连线和显著性标记:
library(ggsignif) ggplot(emm_df, aes(x = Temperature, y = prob, color = Species, group = Species)) + geom_point(size = 3) + geom_errorbar(aes(ymin = asymp.LCL, ymax = asymp.UCL), width = 0.2) + geom_text(aes(label = .group), vjust = -1.5, size = 4) + # 添加物种间差异的连线与标记 geom_signif( data = emm_df, aes(group = Species), comparisons = list(c("HA", "AP")), # 标记位置为每个温度组置信区间最大值上方 y_position = emm_df |> group_by(Temperature) |> summarise(y = max(asymp.UCL) + 0.06) |> pull(y), map_signif_level = TRUE, tip_length = 0.01 ) + labs( x = "Temperature", y = "Predicted probability of reaching 1st instar from egg (± 95% confidence intervals)", color = "Species" ) + theme_classic()
内容的提问来源于stack exchange,提问作者Insect_biologist
相关产品推荐
相关产品推荐

