使用facet_wrap与stat_pvalue_manual时出现size不匹配错误的求助
问题:修改Dunn检验统计结果的y.position后绘图报错
问题背景
数据集示例
Sample_ID group_classification Days_after_infection_1 category post-infection or 1st dose p.i. category# category post-1st dose post 1st dose category# category post-2nd dose post 2nd dose category# abs titers control_classification 120027_1 Control NA 0 0 NA NA NA NA Fractalkine_pg_mL_LOD(100) 5.502690e+03 control_positive 120027_1 Control NA 0 0 NA NA NA NA GM_CSF_pg_mL_LOD(0.12) 0.000000e+00 control_positive 120027_1 Control NA 0 0 NA NA NA NA ITAC_pg_mL_LOD(1.5) 6.178953e+00 control_positive
列名
[1]"Sample_ID" "group_classification" [3] "Days_after_infection_1" "category post-infection or 1st dose" [5] "p.i. category#" "category post-1st dose" [7] "post 1st dose category#" "category post-2nd dose" [9] "post 2nd dose category#" "abs" [11] "titers" "control_classification"
执行代码与报错
先执行Dunn检验并获取位置:
df.dunn.stat <- data.frame(df.tidy.3) %>% group_by(abs) %>% dunn_test(titers ~ group_classification) %>% add_y_position(scales = 'free_y')
因y.position值过大,手动修改为固定值:
df.dunn.stat1 <- df.dunn.stat %>% group_by(abs) %>% mutate(y.position = c(7, 7.5, 8, 8.5, 9, 9.5))
使用ggplot2的facet_wrap分面绘图时,传入修改后的df.dunn.stat1到stat_pvalue_manual报错:
Error in `dplyr::mutate()`: ℹ In argument: `label = as.character(data %>% pull("p.adj.signif"))`. ℹ In group 1: `abs = "GM_CSF_pg_mL_LOD(0.12)"`. Caused by error: ! `label` must be size 2 or 1, not 28.
错误原因
硬编码的y.position向量长度(6个值)与部分abs分组的检验结果行数不匹配。比如GM_CSF_pg_mL_LOD(0.12)分组的检验结果行数不是6,此时dplyr会循环填充该向量,导致该分组的行数被重复扩展,最终行数与stat_pvalue_manual预期的分组检验结果行数不一致,引发标签长度不匹配的错误。
解决方案
1. 按分组实际行数动态生成y.position
不要硬编码固定长度的向量,而是根据每个abs分组内的检验结果行数,自动生成对应长度的位置序列:
df.dunn.stat1 <- df.dunn.stat %>% group_by(abs) %>% mutate( # 从7开始,步长0.5,生成与当前分组行数一致的序列 y.position = seq(from = 7, by = 0.5, length.out = n()) ) %>% ungroup()
2. 先确认各分组的检验结果行数
先排查每个abs分组对应的Dunn检验结果行数,确保后续赋值的向量长度匹配:
# 查看每个abs分组的检验结果行数 df.dunn.stat %>% count(abs)
如果某分组行数不是6,就需要调整y.position的向量长度,或者用方案1的动态生成方式避免硬编码。
3. 基于数据范围动态计算y.position(更优)
如果不同abs的y轴范围差异大,可以结合该分组的titers最大值来计算位置,适配每个分面的实际数据:
# 先计算每个abs的titers最大值 titer_max <- df.tidy.3 %>% group_by(abs) %>% summarise(max_titer = max(titers, na.rm = TRUE)) # 合并最大值到统计结果,生成适配的y.position df.dunn.stat1 <- df.dunn.stat %>% left_join(titer_max, by = "abs") %>% group_by(abs) %>% mutate( # 从最大值的1.1倍开始,按最大值的5%递增,生成对应长度的序列 y.position = seq(from = max_titer * 1.1, by = max_titer * 0.05, length.out = n()) ) %>% ungroup()
内容的提问来源于stack exchange,提问作者Someone_1313
相关产品推荐
相关产品推荐

