R:在箱线图ggplot上显示平均值和中值标签

Posted

技术标签:

【中文标题】R:在箱线图ggplot上显示平均值和中值标签【英文标题】:R: Displaying mean and median labels on boxplot ggplot 【发布时间】:2019-04-02 22:34:39 【问题描述】:

我刚刚开始使用 R 并试图找出如何使用 ggplot 在箱形图上添加均值和中值标签。 我有一个数据集:单位、季度、天数:

dset <- read.table(text='Unit     Quarter  Days   Z  
HH       1Q      25  Y      
PA       1Q      28  N     
PA       1Q      10  Y     
HH       1Q      53  Y
HH       1Q      12  Y
HH       1Q      20  Y
HH       1Q      43  N
PA       1Q      11  Y
PA       1Q      66  Y
PA       1Q      54  Y      
PA       2Q      19  N
PA       2Q      46  Y
PA       2Q      37  Y
HH       2Q      22  Y      
HH       2Q      67  Y      
PA       2Q      45  Y
HH       2Q      48  Y
HH       2Q      15  N
PA       3Q      12  Y               
PA       3Q      53  Y      
HH       3Q      58  Y
HH       3Q      41  N
HH       3Q      18  Y
PA       3Q      26  Y
PA       3Q      12  Y
HH       3Q      63  Y
                   ', header=TRUE)

我需要按单位和季度显示数据,并创建一个显示平均值和中值的箱线图。 我的箱线图代码:

ggplot(data = dset, aes(x = Quarter
                       ,y = Days, fill = Quarter))  +
  geom_boxplot(outlier.shape = NA) + 
  facet_grid(. ~ Unit) + # adding another dimension
  coord_cartesian(ylim = c(10, 60)) + #sets the y-axis limits
  stat_summary(fun.y=mean, geom="point", shape=20, size=3, color="red", fill="red") + #adds average dot
  geom_text(data = means, aes(label = round(Days, 1), y = Days + 1), size = 3) + #adds average labels
  geom_text(data = medians, aes(label = round(Days, 1), y = Days - 0.5), size = 3) + #adds median labels
  xlab(" ") +
  ylab("Days") +
  ggtitle("Days") +
  theme(legend.position = 'none')

我可以使用 geom_text 函数添加均值和中值标签,但仅限于一维(“季度”),它需要预先计算均值和中值变量:

means <- aggregate(Days ~  Quarter, dset, mean)
medians <- aggregate(Days ~  Quarter, dset, median)

效果很好,我设法通过“单位”和“季度”计算了平均值和中值:

means <- aggregate(dset[, 'Days'], list('Unit' = dset$Unit, 'Quarter' = dset$Quarter), mean)
medians <- aggregate(dset[, 'Days'], list('Unit' = dset$Unit, 'Quarter' = dset$Quarter), median)

但我不知道如何将这些变量传递给 geom_text 函数以显示均值和中位数的标签。也许我应该以不同的方式计算平均值和中位数,或者还有其他选项如何添加这些标签。 如有任何建议,将不胜感激!

【问题讨论】:

看看这个***.com/questions/19876505/… @prosoitos 我以前读过那篇文章,但它没有告诉你如果你使用二维,在我的例子中是“单位”和“季度”,如何获取标签。 在中位数和均值上添加标签也没什么 哦,对不起。我认为它会很有用 有什么帮助,你能帮忙解决另一个相应的问题吗?如果我想使用另一列“Z”找到数据子集的平均值,我应该如何更改 means &lt;- aggregate(dset[, 'Days'], list('Unit' = dset$Unit, 'Quarter' = dset$Quarter), mean) 【参考方案1】:

看起来问题在于,当您按“单位”和“季度”计算平均值和中值时,以前称为“天”的变量现在称为“x”。因此,只需更新您的 geom_text 命令以反映这一点。

ggplot(data = dset, aes(x = Quarter, y = Days, fill = Quarter))  +
  geom_boxplot(outlier.shape = NA) + 
  facet_grid(. ~ Unit) + # adding another dimension
  coord_cartesian(ylim = c(10, 60)) + #sets the y-axis limits
  stat_summary(fun.y=mean, geom="point", shape=20, size=3, color="red", fill="red") + #adds average dot
  geom_text(data = means, aes(label = round(x, 1), y = x + 1), size = 3) + #adds average labels
  geom_text(data = medians, aes(label = round(x, 1), y = x - 0.5), size = 3) + #adds median labels
  xlab(" ") +
  ylab("Days") +
  ggtitle("Days") +
  theme(legend.position = 'none')

【讨论】:

太棒了!谢谢莎拉! 你能帮忙解决另一个相应的问题吗?如果我想使用另一列“Z”找到数据子集的平均值,我应该如何更改 means &lt;- aggregate(dset[, 'Days'], list('Unit' = dset$Unit, 'Quarter' = dset$Quarter), mean) 我试过means &lt;- aggregate(subset(dset[, 'Days', 'Z'], Z=="Y"), list('Unit' = dset$Unit, 'Quarter' = dset$Quarter), mean),但它不起作用... 我想这就是你要找的:【参考方案2】:

在回答您的第二个问题时,我认为您正在寻找类似的东西。此代码生成相同的图表,但仅限于子样本 Z = Y

means <- aggregate(dset[, 'Days'][dset$Z=="Y"], list('Unit' = dset$Unit[dset$Z=="Y"], 'Quarter' = dset$Quarter[dset$Z=="Y"]), mean)
    medians <- aggregate(dset[, 'Days'][dset$Z=="Y"], list('Unit' = dset$Unit[dset$Z=="Y"], 'Quarter' = dset$Quarter[dset$Z=="Y"]), median)

ggplot(data = dset[dset$Z=="Y",], aes(x = Quarter, y = Days, fill = Quarter))  +
  geom_boxplot(outlier.shape = NA) + 
  facet_grid(. ~ Unit) + # adding another dimension
  coord_cartesian(ylim = c(10, 60)) + #sets the y-axis limits
  stat_summary(fun.y=mean, geom="point", shape=20, size=3, color="red", fill="red") + #adds average dot
  geom_text(data = means, aes(label = round(x, 1), y = x + 1), size = 3) + #adds average labels
  geom_text(data = medians, aes(label = round(x, 1), y = x - 0.5), size = 3) + #adds median labels
  xlab(" ") +
  ylab("Days") +
  ggtitle("Days") +
  theme(legend.position = 'none')

【讨论】:

这也很好用,谢谢!不过,我注意到如果我在 Z 列中有“NA”值,箱线图会显示 3 个图表:2 个表示单位,1 个表示“NA”。我还设法通过创建一个临时表来编写另一个选项:tdf &lt;- subset(dset, Z=="Y", select = c('Days', 'Unit', 'Quarter')),然后只使用“tdf”表而不是“dset”:means &lt;- aggregate(tdf[, 'Days'], list('Unit' = tdf$Unit, 'Quarter' = tdf$Quarter), mean) 至于避免使用“NA”记录的图表,我稍微改变了这一行:ggplot(data = subset(dset, Z=="Y"), aes(x = Quarter, y = Days, fill = Quarter))...

以上是关于R:在箱线图ggplot上显示平均值和中值标签的主要内容,如果未能解决你的问题,请参考以下文章

如何使用ggplot2显示箱线图中的所有平均值? [复制]

如何在ggplot的箱线图中按组绘制平均值

R语言ggplot2可视化在箱图中为箱图添加均值的标签及对应数值实战

R语言ggplot2可视化:自定义函数在箱图(boxplot)上添加分组样本个数(count)分组均值(mean)箱体填充色自定义数据标签色彩自定义

Boxplot ggplot2:在分组箱线图中显示平均值和观察次数

R:ggrepel,ggplot2 绘图区域上方的标签