如何在ggplot2的箱线图中添加每组观测值数量并使用组均值?

26

我正在制作一个基本的箱线图,其中y=年龄x=病人组

age <- ggplot(data, aes(factor(group2), age))  + ylim(15, 80) 
age + geom_boxplot(fill = "grey80", colour = "#3366FF")

我希望你能帮我解决以下几个问题:

1)是否可能在每个分组箱线图上方包含一些观测值的数量(但不是在我的分组标签所在的X轴上),而不必使用画图软件? 我已经尝试过使用:

age + annotate("text", x = "CON", y = 60, label = "25")

其中,CON是第一个组,y = 60大致在该组的箱线图上方。然而,该命令并没有起作用。我猜想这可能与它将x读为连续变量而不是分类变量有关。

2) 另外,虽然有很多关于在箱线图中使用均值而不是中位数的问题,但我仍然没有找到适合我的代码?

3) 在同一问题上,是否有一种方式可以在箱线图中包含平均组统计信息?也许使用

age + stat_summary(fun.y=mean, colour="red", geom="point")

然而,这仅包括均值所在位置的一个点。或者再次使用

age + annotate("text", x = "CON", y = 30, label = "30")

其中CON是第一组,y = 30是该组年龄平均值。鉴于ggplot2语法的灵活性和丰富性,我希望有一种更优雅的方式来使用实际统计结果而不是annotate

任何建议/链接将不胜感激!

谢谢!!


一个箱线图通常具有最小值、下四分位数、中位数和上四分位数,最后是最大值。您已经拥有了0.25、0.5和0.75分位数。这不够信息丰富吗? - Arun
这是我被要求提供的格式。 - user1442363
3个回答

39

这是否与您想要的类似?使用stat_summary,如所请求的:

# function for number of observations 
give.n <- function(x){
  return(c(y = median(x)*1.05, label = length(x))) 
  # experiment with the multiplier to find the perfect position
}

# function for mean labels
mean.n <- function(x){
  return(c(y = median(x)*0.97, label = round(mean(x),2))) 
  # experiment with the multiplier to find the perfect position
}

# plot
ggplot(mtcars, aes(factor(cyl), mpg, label=rownames(mtcars))) +
  geom_boxplot(fill = "grey80", colour = "#3366FF") +
  stat_summary(fun.data = give.n, geom = "text", fun.y = median) +
  stat_summary(fun.data = mean.n, geom = "text", fun.y = mean, colour = "red")

黑色数字是观测次数,红色数字是平均值。joran的答案向您展示了如何将数字放置在方框的顶部。 enter image description here 致谢:https://dev59.com/TnA75IYBdhLWcg3wFE2b#3483657

3
关于如何添加 n = 11 标注等变化,请参见此答案的变体:https://dev59.com/0WUo5IYBdhLWcg3w2CaJ#15720769 - Ben

18

我想这可能是你在寻找的东西?

myboxplot <- ddply(mtcars,
                    .(cyl),
                    summarise,
                    min = min(mpg),
                    q1 = quantile(mpg,0.25),
                    med = median(mpg),
                    q3 = quantile(mpg,0.75),
                    max= max(mpg),
                    lab = length(cyl))
ggplot(myboxplot, aes(x = factor(cyl))) + 
    geom_boxplot(aes(lower = q1, upper = q3, middle = med, ymin = min, ymax = max), stat = "identity") + 
    geom_text(aes(y = max,label = lab),vjust = 0)

enter image description here

我刚刚意识到当你在询问平均值时,我错误地使用了中位数,但是您可以根据自己的需要使用任何函数来设置middle美学属性。


抱歉,最后一个问题。更改组的顺序是否可能?不幸的是,我对数字或数据驱动的顺序不感兴趣。我能想到的唯一方法是重新编码组变量。非常感谢您的帮助!再次感谢! - user1442363

4

第一个问题的答案。 要在框上方显示值,您应该提供数值而不是级别名称作为x值。因此,要绘制第一个值上方的值,请给出x = 1

data(ToothGrowth)
ggplot(ToothGrowth,aes(supp,len))+geom_boxplot()+
   annotate("text",x=1,y=32,label=30)

嗨!太好了,谢谢。我最初尝试了数字/级别,但出于某种原因没有起作用。现在没问题了,非常感谢。 - user1442363
注释命令非常适合解决定位问题!非常感谢。 - Mac

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接