如何仅移除ggpaired图小提琴部分的零值?ggplot_build使用异常
问题:移除ggpaired图中小提琴部分的零值,却意外丢失统计检验
想要仅移除ggpaired图中小提琴部分的零值,尝试用ggplot_build处理后没达到预期,还弄丢了原本的统计检验标注。
原代码
library(introdataviz) library(ggpubr) library(grid) #set seed set.seed(42) #build dunny data first <- sample(c(rep(0,100), rnorm(50,15,2))) second <- sample(c(rep(0,100), rnorm(50,10,1))) df <- data.frame(first, second) # build plot p1 <- ggpaired(df,cond1 = "first", cond2 = "second",line.color = "gray")+ stat_compare_means(paired = TRUE)+ introdataviz::geom_split_violin( trim = TRUE,alpha = .4) + ylim(0,22) #create ggplot_build object p1_build <- ggplot_build(p1) #remove zeros from violin plot part p1_build$data[[4]] <- subset(p1_build$data[[4]], first != 0 & second != 0) p1_build$data[[5]] <- subset(p1_build$data[[5]], first != 0 & second != 0) #produce new graph p2 <- ggplot_gtable(p1_build) grid.draw(p2)
错误原因分析
- 筛选条件无效:
ggplot_build生成的数据是长格式,每个小提琴图层只对应一组数据(要么是first,要么是second),不存在同时包含first和second的列,用first !=0 & second !=0筛选完全起不到删零值的作用。 - 图层操作风险:如果误修改了统计检验对应的图层数据,就会导致检验标注直接消失。
修正方案
步骤1:确认小提琴图层的索引
先运行以下代码查看每个图层的类型,定位geom_split_violin对应的图层索引:
sapply(p1_build$plot$layers, function(x) class(x$geom)[1])
geom_split_violin通常会生成两个图层(左右各一个),对应索引比如4和5。
步骤2:正确筛选零值
针对小提琴图层的y列(对应数值)筛选掉y=0的行,不要触碰统计检验的图层:
library(introdataviz) library(ggpubr) library(grid) set.seed(42) # 构建模拟数据 first <- sample(c(rep(0,100), rnorm(50,15,2))) second <- sample(c(rep(0,100), rnorm(50,10,1))) df <- data.frame(first, second) # 绘制初始图 p1 <- ggpaired(df, cond1 = "first", cond2 = "second", line.color = "gray") + stat_compare_means(paired = TRUE) + introdataviz::geom_split_violin(trim = TRUE, alpha = .4) + ylim(0,22) # 生成ggplot_build对象 p1_build <- ggplot_build(p1) # 筛选小提琴图层中的零值(假设第4、5个是小提琴图层) p1_build$data[[4]] <- subset(p1_build$data[[4]], y != 0) p1_build$data[[5]] <- subset(p1_build$data[[5]], y != 0) # 生成并绘制修正后的图 p2 <- ggplot_gtable(p1_build) grid.draw(p2)
这样就能只移除小提琴部分的零值,同时保留统计检验标注。
内容的提问来源于stack exchange,提问作者Michl
相关产品推荐
相关产品推荐

