如何在 R 中使用 ggplot2 在箱线图的每个四分位数中包含观察数?

How to include number of observations in each quartile of boxplot using ggplot2 in R?

我正在绘制箱线图以查看变量的分布。我也有兴趣查看每个四分位数的观察次数。有什么方法可以将每个四分位数的观察值数量与四分位数的值一起添加到箱线图中吗?

我在下面包含了一些代码,可以生成带有四分位数值的箱线图。

df <- datasets::iris
boxplot <- ggplot(df, aes(x = "", y = Sepal.Length)) +
  geom_boxplot(width=0.1, position = "dodge", fill = "red") +
  stat_boxplot(geom = "errorbar", width = 0.1) +
  stat_summary(geom = "label_repel", fun.y = quantile, aes(label = ..y..),
               position = position_nudge(x = -0.1), size = 3) +
  ggtitle("") +
  xlab("") +
  ylab('Sepal.Length')

如果可能的话,我期望图左侧的四分位数值和图右侧的观察值数。

这是一种可能。我总是更喜欢将我的额外数据作为额外的数据框,因为这让我可以更好地控制计算方式。

中汲取灵感进行计数
quantile_counts=function(x){
 df= data.frame(label=table(cut(x, quantile(x))),
             label_pos=diff(quantile(x))/2+quantile(x)[1:4])
 return(df)
}

df_quantile_counts=quantile_counts(df$Sepal.Length)

boxplot <- ggplot(df, aes(x = "", y = Sepal.Length)) +
  geom_boxplot(width=0.1, position = "dodge", fill = "red") +
  stat_boxplot(geom = "errorbar", width = 0.1) +
  stat_summary(geom = "label", fun.y = quantile, aes(label = ..y..),
               position = position_nudge(x = -0.1), size = 3) +
  geom_text(data=df_quantile_counts,aes(x="",y=label_pos,label = label.Freq),
            position = position_nudge(x = +0.1), size = 3) +
  ggtitle("") +
  xlab("") +
  ylab('Sepal.Length')

HTH,托比

@TobiO 的回答是正确的。但是,我的数据有点倾斜,一些切点是相同的(例如第一个和第二个切点相同)。我需要采用唯一值来计算每个四分位数中的观察次数。另一点与 cut 函数的使用有关,它不包括起点(下限、上限)。为了包括起点,我使用了 cut2 中的函数 Hmisc 包。我包含了一条 label_pos_extension 线,以防止切割点彼此非常接近的四分位数的 label/text 重叠。geom_text_repel 无法防止重叠。

quantile_counts2 <- function(x){
  label_pos_extension <- c(0,3,4,0)
  if(length(unique(quantile(x))) < 5){
    df <- data.frame(label = table(cut2(x, g = 4)),
                 label_pos =  c(0, diff(unique(quantile(x))) / 2 + quantile(x)[1:length(unique(quantile(x)))-1]) + label_pos_extension[1:length(unique(quantile(x)))])
  } else {
    df <- data.frame(label = table(cut2(x, g = 4)),
                 label_pos = diff(quantile(x)) / 2 + quantile(x)[1:4] + label_pos_extension)
  } return(df)
}

PS。我试图将我编辑的功能放在评论中,但是它没有用。