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

R 箱线图ggplot2:在分组箱线图中显示观察值的平均值和数量,r,ggplot2,mean,boxplot,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轴标签外,还显示观察值的数量,它看起来像这样:(“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")

give.nTL;DR-您需要提供一个
组=
美观,因为
ggplot2
不知道应该在哪列数据上隐藏文本geom

不幸的是,我们没有您的数据,但这里有一个示例集,可以展示
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)
现在,这里是带躲闪的
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)
  )

如果您提供另一种美学,如
颜色=
填充=
,则不必提供
组=
美学。如果您同时给出了
颜色=
组=
美学效果,则
组=
美学效果将覆盖其他任何美学效果,以达到规避目的。这里有一个相同的示例,但您不需要使用
组=
美学,因为我已将
颜色=
向上移动到
aes()
(将填充更改为灰度以便您可以看到文本):

有趣的事实:即使你提供的
geom_text()
带有一种通常适用于躲避的无意义美学,例如
fill=
,躲避仍然有效。您会收到一条警告消息
忽略未知美学: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\u summary()
行更改为该行应该可以:

stat_summary(aes(x = Slope, y = Events.g_Bacteria, group = Detergent),...

没有任何样本数据,很难做出好的推荐。看见我最好的猜测是,您的问题是stat_summary不是继承aes,而是定义一个新的aes,它不包括洗涤剂。因此,代码将文本放在箱线图所在的位置,如果它们没有根据清洗剂系数分开的话。这只是我最好的猜测。HTHIt可能更容易使用geom_文本作为样本大小和平均值-您可以设置x和y坐标,例如geom_文本(aes(x=Slope,y=min(Events.g.bacteria),label=give.n))+geom_文本(aes(x=Slope,y=1.1*min(Events.g.bacteria),label=mean.n))应将样本编号放在底部,平均值正好在其上方。您可能需要稍微调整一下比例(例如,0.9*min(…),等等)。另一个可能的想法是
fill
参数在facet和x变量的组合之间分割数据。但中值和均值函数使用给定组合中的所有值。特别是,有多少行数据适合
AL_S
Buot
方面?有9个吗?
p + geom_text(data=summary_df,
      aes(y=m, label=round(m,2), color=detergent),
      position=position_dodge(0.8)
  ) + scale_fill_grey()
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(aes(x = Slope, y = Events.g_Bacteria, group = Detergent),...