Hide box and whiskers in geom_boxplot() when N is small
我经常进行箱线图绘制,其中一些类别很小,而其他类别则有大量数据,并与抖动的原始数据点叠加在一起。我正在寻找一种隐藏小类别(N <5)类别的盒子和晶须的可靠方法。目的是使这些小类别使用geom_point()层仅显示原始数据,但是有意义的类别将得到"盒须"处理。在我看来,将geom_boxplot()层中的alpha映射到基于N的因子变量的事情似乎不起作用,因为alpha只控制填充,可能控制geom_boxplot中的异常值,而不是盒子和晶须。
过去,只要我愿意将颜色参数浪费在这个问题上,我就会找到一个可行的解决方案。但是,通常我想将颜色实际用于其他用途,并且将其两次映射会导致粗糙的输出。我想到的另一种混乱的解决方案是使用已删除了小类别的数据子集-该计划的问题在于,当这些类别要受position_dodge()约束时,它将无法正确处理情况(如闪避将""类别太少)。
下面的最小示例。
1 2 3 4 5 6 7 8 9 | df <- data.frame(group=factor(sample(c("A","B"), size=110, replace=TRUE)), sex=factor(c(rep("M",50), rep("F", 50), rep("NB", 10))), height=c(rnorm(50, 70, 6), rnorm(50, 63, 6), rnorm(10, 65, 6))) dfsub <- filter(df, !(sex=="NB" & group=="A")) ggplot(df, aes(x=group, y=height, colour=sex)) + geom_boxplot(data=dfsub) + geom_point(position=position_jitterdodge(jitter.width=0.2)) |
我为您的身高数据做了第二列,其中小样本量组中的值被替换为
要使框线图和点正确对齐,请使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | require(tidyverse) df <- data.frame(group = factor(sample(c("A","B"), size = 110, replace = TRUE)), sex = factor(c(rep("M", 50), rep("F", 50), rep("NB", 10))), height = c(rnorm(50, 70, 6), rnorm(50, 63, 6), rnorm(10, 65, 6))) n <- df %>% #calculate sample sizes group_by(group, sex) %>% summarize(n = n()) df <- left_join(df, n) %>% #join sample sizes to df #make second height column to use for boxplots: NA values if n is too small mutate(boxplot_height = ifelse(n < 5, NA, height)) ggplot(df, aes(x = group, colour = sex)) + #use height column that has groups with n < 5 coded as NA to plot boxplots geom_boxplot(aes(y = boxplot_height), #preserve ="single" maintains constant width of boxes position = position_dodge(preserve ="single")) + geom_point(aes(y = height), #use all height data as y variable for points position = position_jitterdodge(jitter.width = 0.2)) |
好的,我认为这种方式不一定比您当前的选择更好,但是...您可以将df分解为boxplot和scatterplot的dfs,然后将要从boxplot中删除的数据的值修改为超出范围(例如此处为1000)。然后将两者绘制,最后使用
要创建
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | df <- data.frame(group=factor(sample(c("A","B"), size=110, replace=TRUE)), sex=factor(c(rep("M",50), rep("F", 50), rep("NB", 10))), height=c(rnorm(50, 70, 6), rnorm(50, 63, 6), rnorm(10, 65, 6))) df_box <- df %>% group_by(group, sex) %>% mutate(temp = ifelse(n() < 5, 1000, 1)) %>% ungroup() %>% mutate(height = ifelse(temp == 1000, 1000, height)) %>% select(-temp) ggplot(df, aes(x=group, y=height, colour=sex)) + geom_boxplot(data=df_box) + geom_point(position=position_jitterdodge(jitter.width=0.2)) + coord_cartesian(ylim=c(50,90)) |