箱线图ggplot2:在分组箱线图中显示平均值和观测值数量

时间:2020-06-17 16:31:41

标签: r ggplot2 mean boxplot

我希望在该箱图中添加观察值,而不是按组而是按因子分开。另外,除了x轴标签外,我还希望显示观察次数:(“ PF(N = 12)”)。 此外,我想在框内显示每个框的平均值,以百万为单位显示,以便每个框都没有大数。

这就是我所拥有的:

    give.n <- function(x){
    return(c(y = median(x)*1.05, label = length(x)))
    }

    mean.n <- function(x){x <- x/1000000
    return(c(y = median(x)*0.97, label = round(mean(x),2)))
    }


    ggplot(Soils_noctrl) +  
    geom_boxplot(aes(x=Slope,y=Events.g_Bacteria, fill = Detergent), 
               varwidth = TRUE) +
    stat_summary(aes(x = Slope, y = Events.g_Bacteria), fun.data = give.n, geom = "text", 
               fun = median,
               position = position_dodge(width = 0.75))+
    ggtitle("Cell Abundance")+
    stat_summary(aes(x = Slope, y = Events.g_Bacteria), 
               fun.data = mean.n, geom = "text", fun = mean, colour = "red")+
    facet_wrap(~ Location, scale = "free_x")+
    scale_y_continuous(name = "Cell Counts per Gram (Millions)", 
                     breaks = round (seq(min(0), 
                                         max(100000000), by = 5000000),1),
                     labels = function(y) y / 1000000)+
    xlab("Sample")

到目前为止,它看起来像这样: As you can see, the mean value is at the bottom of the plot and the number of observations are in the boxes but not separated

谢谢您的帮助!干杯

1 个答案:

答案 0 :(得分:0)

TL; DR-您需要提供group=的美感,因为ggplot2不知道应该在哪个列数据上闪避文本几何。

很遗憾,我们没有您的数据,但是这里有一个示例集,可以展示这里的原理以及group=的功能/需求。

set.seed(1234)
df1 <- data.frame(detergent=c(rep('EDTA',15),rep('Tween',15)), cells=c(rnorm(15,10,1),rnorm(15,10,3)))
df2 <- data.frame(detergent=c(rep('EDTA',20),rep('Tween',20)), cells=c(rnorm(20,1.3,1),rnorm(20,4,2)))
df3 <- data.frame(detergent=c(rep('EDTA',30),rep('Tween',30)), cells=c(rnorm(30,5,0.8),rnorm(30,3.3,1)))

df1$smp='Sample1'
df2$smp='Sample2'
df3$smp='Sample3'

df <- rbind(df1,df2,df3)

代替使用stat_summary(),我将创建一个单独的数据框来保存要作为文本包含在绘图中的平均值:

summary_df <- df %>% group_by(smp, detergent) %>% summarize(m=mean(cells))

现在,这是geom_text()与闪避一起使用的情节和用法:

p <- ggplot(df, aes(x=smp, y=cells)) +
  geom_boxplot(aes(fill=detergent))

p + geom_text(data=summary_df,
    aes(y=m, label=round(m,2)),
    color='blue', position=position_dodge(0.8)
  )

enter image description here

您会发现数字都沿y=分隔开了,但是“躲避”无效。这是因为我们没有提供有关如何进行躲避的任何信息。在这种情况下,可以提供group=的美感,以使ggplot2知道这是用于闪避的列:

p + geom_text(data=summary_df,
    aes(y=m, label=round(m,2), group=detergent),
    color='blue', position=position_dodge(0.8)
  )

enter image description here

如果您提供group=color=之类的其他美学,您就没有必须提供。如果您同时给出了fill=color=美观性,则group=美观性会优先于其他目的,以进行躲避。这是一个相同的示例,但是您不需要group=的美感,因为我已经将group=上移到color=中(将填充更改为灰度,以便可以看到文字):

aes()

enter image description here

有趣的事实:即使您向p + geom_text(data=summary_df, aes(y=m, label=round(m,2), color=detergent), position=position_dodge(0.8) ) + scale_fill_grey() 提供了通常可以用于躲避的无意义的审美,例如geom_text(),躲避仍然有效。您收到警告消息fill=,但闪避仍然有效:

Ignoring unknown aesthetics: fill

对于您而言,将p + geom_text(data=summary_df, aes(y=m, label=round(m,2), fill=detergent), position=position_dodge(0.8) ) # gives you the same plot as if you just supplied group=detergent, but with black text 行更改为该行应该有效:

stat_summary()