当N小时隐藏geom_boxplot()中的盒子和晶须

时间:2019-10-09 21:44:47

标签: r ggplot2 boxplot

我经常进行箱线图绘制,其中某些类别很小,而其他类别则有大量数据,并与抖动的原始数据点叠加在一起。我正在寻找一种隐藏小类别(N <5)类别的盒子和晶须的可靠方法。目的是使这些小类别使用geom_point()层仅显示原始数据,但有意义的类别将获得“盒须”处理。在我看来,将geom_boxplot()层中的alpha映射到基于N的因子变量的事情似乎不起作用,因为alpha只控制填充,可能控制geom_boxplot中的异常值,而不是盒子和晶须。

过去,只要我愿意将颜色参数浪费在这个问题上,我就会找到一个可行的解决方案。但是,通常我想将颜色实际用于其他用途,并且将其两次映射会导致粗糙的输出。我想到的另一种混乱的解决方案是使用已从中删除了小类别的数据子集-该计划的问题在于,当这些类别受到position_dodge()约束时,它将无法正确处理情况(因为闪避会“ “类别太少)。

下面的最小示例。

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))

2 个答案:

答案 0 :(得分:1)

好的,我认为这种方式不一定比您当前的选择更好,但是...您可以将df分解为箱图和散点图的dfs,然后修改要从中删除的数据的值箱线图超出范围(例如此处为1000)。然后同时绘制两者,最后使用coord_cartesian放大相关部分。

要创建df_box,请按groupsex进行分组,然后将具有<5个数据点的组的值更改为1000(这样,更改值的代码)。

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))

image

答案 1 :(得分:1)

我在第二列中输入了您的身高数据,其中小样本量组中的值被替换为NA。绘制数据时,将原始高度列用作点的y美观,将新的具有NA值的小列用作盒图的y美观。

要使框线图和点正确对齐,请使用geom_boxplot(position_dodge(preserve = "single"))告诉ggplot为框线图保持恒定的宽度,即使缺少数据也是如此。

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))

enter image description here