R语言SIBER包极坐标柱状图缺失值与y轴标准化问题
解决极坐标分面图的y轴标准化问题
问题根源
原教程中,直方图计数的标准化是按每个comparison组单独计算(除以自身组内的最大计数),但当切换为按TestName分面后,同一分面下包含多个comparison组,会引发两个问题:
- 不同组的标准化基准不统一,组间无法在同一尺度下比较
geom_bar默认堆叠显示,多个组叠加后高度会超过1,触发y轴截断警告(即提示的缺失值),这也是放大y轴能看到值超过1的核心原因
修正方案
1. 调整标准化逻辑:按TestName分面全局标准化
将标准化基准从单个comparison组,改为同一TestName下所有组的计数最大值,确保同一分面内所有组使用统一尺度,保证组间可比性。
2. 修正数据处理代码
替换原有的手动赋值TestName和标准化步骤,改用更可靠的分组逻辑:
# 为每个comparison分配对应的TestName(替代手动rep赋值,避免出错) angles_distances_with_test <- angles_distances %>% mutate(TestName = case_when( # 根据实际分组对应关系调整,这里模拟原数据的分配规则 comparison %in% unique(hist.by.groups_deg$comparison)[1:5] ~ "A", comparison %in% unique(hist.by.groups_deg$comparison)[6:10] ~ "B", TRUE ~ "C" )) # 生成直方图后,按TestName全局标准化计数 hist.by.groups_deg <- angles_distances_with_test %>% group_by(TestName, comparison) %>% do(my.hist(.)) %>% ungroup() %>% # 关键:按TestName分组,用该组内的最大计数统一标准化 group_by(TestName) %>% mutate(counts.stdzd_global = counts / max(counts)) %>% ungroup() %>% mutate(Degrees = mids*(180/pi))
3. 修改绘图代码
将y轴映射改为全局标准化后的counts.stdzd_global,并明确设置geom_bar的位置为identity(避免堆叠导致高度超标):
cols <- c("#0570b0", "#8c96c6", "#74a9cf", "#8856a7", "#d7b5d8", "#b3cde3", "#810f7c", "#66c2a4", "#bdc9e1", "#df65b0","salmon","pink","gray","beige","tan") all.roses <- ggplot(data = hist.by.groups_deg, aes(x = Degrees, y = counts.stdzd_global, color = comparison, fill = comparison)) + geom_hline(yintercept = seq(0, 1, by = 0.25), colour = "grey90", linewidth = 0.2) + geom_vline(xintercept = seq(0, 180, by = 45), colour = "grey90", linewidth = 0.2) + geom_vline(xintercept = seq(0, -180, by = -45), colour = "grey90", linewidth = 0.2) + # 显式设置position=identity,避免默认堆叠导致高度超过1 geom_bar(stat = "identity", alpha = .7, position = "identity") + scale_x_continuous( limits = c(-180,180), breaks = c(-180, -90, 0, 90, 180), labels = c("","-90","0","90", "")) + scale_y_continuous( limits = c(0,1), expand = c(0,0)) + # 去除y轴空白,贴合极坐标边界 coord_polar(start = pi/2, direction = -1) + facet_wrap( ~ TestName, nrow = 2) + scale_fill_manual(values = cols) + scale_color_manual(values = cols) + theme(axis.ticks.y = element_blank(), axis.text.y = element_blank(), legend.position = "none", panel.border = element_blank(), panel.grid = element_blank()) + labs(y = "Counts (standardized within each test group)", x = "Angle between ellipse centroids (°)") print(all.roses)
效果说明
- 同一分面内所有组的计数都基于该分面的最大计数缩放,y轴严格保持0-1范围,不会出现截断警告
- 组间可以在同一尺度下直接比较分布特征
- 避免了
geom_bar堆叠导致的高度异常问题
内容的提问来源于stack exchange,提问作者ElizaBeso000
相关产品推荐
相关产品推荐

