【问题标题】:Sample size over whiskers of boxplot箱线图上的样本量
【发布时间】:2019-10-07 23:38:54
【问题描述】:

我想在每个箱线图的胡须上显示“n = (n)”。我已经想出了如何使用 Fivenum 将这些标签放在每个盒子(q75)的顶部,但我无法让它们在晶须上方工作。胡须上方更好,因为我的情节非常混乱。

在这里,我使用 mtcars 重现了这些情节 编辑: mtcars 没有明显的异常值,但我的数据集有。这就是为什么标签需要位于晶须顶部,而不仅仅是最高数据点的原因。

旁注:我正在处理大量异常值,并希望将它们从显示中删除。 GGplot 可以做到这一点,但它仍然会在轴中包含异常值,这给了我一个非常“缩小”的图。我的解决方法包括在内。我使用了基本箱线图函数来计算最高须线,并使用 coord_cartesian 将上限设置在此之上。

> data("mtcars")
> head(mtcars)
                   mpg cyl disp  hp drat    wt  qsec vs am gear carb
Mazda RX4         21.0   6  160 110 3.90 2.620 16.46  0  1    4    4
Mazda RX4 Wag     21.0   6  160 110 3.90 2.875 17.02  0  1    4    4
Datsun 710        22.8   4  108  93 3.85 2.320 18.61  1  1    4    1
Hornet 4 Drive    21.4   6  258 110 3.08 3.215 19.44  1  0    3    1
Hornet Sportabout 18.7   8  360 175 3.15 3.440 17.02  0  0    3    2
Valiant           18.1   6  225 105 2.76 3.460 20.22  1  0    3    1
> 
> d = data.table(mtcars)
> 
> give.n <- function(x){
+   return(data.frame(y = fivenum(x)[4],
+                     label = paste("n =",length(x))))
+ }
> 
> p1 <- boxplot(mpg~cyl, data=mtcars, outline=FALSE,
+               plot=0)
> p1stats <- p1$stats[5,]
> head(p1stats)
[1] 33.9 21.4 19.2
> upperlim <- max(p1$stats, na.rm = TRUE) * 1.05
>   
> p <- ggplot(d, aes(x=factor(cyl), y=mpg)) +
+     geom_boxplot() +
+ stat_summary(fun.data = give.n, geom = "text", vjust=-.5)
> 
> p <- p + coord_cartesian(ylim = c(0, upperlim))

我尝试更改此功能(有效):

> give.n <- function(x){
+   return(data.frame(y = fivenum(x)[4],
+                     label = paste("n =",length(x))))
+ }

为此,使用 p1 统计数据的第 5 行(上胡须):

give.n <- function(x){
  return(data.frame(y = p1stats,
                    label = paste("n =",length(x))))
}

但这会返回: bad plot

如何让这个标签只显示在每个盒子的正确胡须点上?

PS - 抱歉,我不熟悉在这里发帖,但我试过了

【问题讨论】:

    标签: r ggplot2 rstudio


    【解决方案1】:

    编辑:请参阅下面的评论和我的其他答案!

    好的,我用艾伦的答案的格式想通了。它需要 boxplot.stats 来获得正确的胡须计算:

    geom_text(data=mtcars %>% group_by(cyl) %>%
                summarise(n = n(),
                          boxstats = boxplot.stats(mpg)[1],
                          whisker = boxstats[5]),
                aes(x=cyl, y=whisker, label=paste0("n =", n)))
    

    【讨论】:

    • 这仍然不完美。结果 geom_boxplot 和 boxplot.stats 以不同的方式计算四分位数。我相信一个包括中位数,另一个不包括。这就是 QUARTILE.INC 和 QUARTILE.EXC 在 excel 中的区别。仍然工作得很好,但有些标签可能会稍微偏离晶须,尤其是在样本量较小的情况下
    【解决方案2】:

    好的,从最后一次尝试开始。我想到了。 boxplot.stats 和 geom_boxplot 以不同的方式计算四分位数统计数据,这会在小样本量中扭曲所有内容。我们可以用 ggplot_build 调用 geom_boxplot 使用的实际统计数据。

    这就是它的完成方式,儿子。首先,制作你的情节,就像上面一样,我称之为 p。 现在计算每个 x 变量的样本量

    samp <- count(mtcars, cyl)
    

    现在使用 ggplot_build 从图中检索数据

    ggstat <- ggplot_build(p)$data
    ggwhisk1 <- ggstat[[1]]$ymax
    

    现在将其与样本大小相结合,并在 geom_text 中调用该数据

    ggwhisk2 <- data.frame(samp, whisk = ggwhisk1)
    p <- p + geom_text(data = ggwhisk2, size = 2,
    aes(x = cyl, y = whisk, label = paste0("n =", n), vjust = -.5))
    

    瞧!!

    【讨论】:

      【解决方案3】:

      这是一个带有 dpylr 的 ggplot 解决方案:

      ggplot(mtcars, aes(x=cyl, y=mpg, group=cyl)) + 
        geom_boxplot() + 
        geom_text(data=mtcars %>% group_by(cyl) %>% summarise(top = max(mpg), n=n()), aes(x=cyl, y=top, label= paste0("n = ", n)), nudge_y=1)
      

      编辑

      可能有更简洁的方法,但我认为这可行。我为 cyl=8 编辑了一个数据点以进行强调:

       ggplot(mtcars, aes(x=cyl, y=mpg, group=cyl)) + 
        geom_boxplot() + 
        geom_text(data=mtcars %>% 
                    group_by(cyl) %>% 
                    summarise(q3 = quantile(mpg, 0.75),
                              q1 = quantile(mpg, 0.25),
                              iqr = q3 - q1,
                              top = min(q3 + 1.5*iqr, max(mpg)), 
                              n=n()), 
                  aes(x=cyl, y=top, label= paste0("n = ", n)), nudge_y=1)
      

      【讨论】:

      • 所以这可以通过将标签放在每个盒子/组的最高值上,而不是在晶须上。在具有大量异常值的数据集中,它们将不在屏幕上。
      • 抱歉造成误会。编辑了帖子以说明这一点。
      • 谢谢。这几乎是完美的,但还有另一个问题。它适用于具有均匀样本量的任何组。当样本量为奇数时,变量“top”返回 q3 + 1.5*iqr,而不是返回该范围内的最大水平。试图弄清楚这一点。编辑:所以我想问题是 q3 +1.5*iqr 不是数据点。 geom_boxplot 晶须是数据集中小于 q3 + 1.5* iqr 的最大点。这就是为什么我试图从我用来定义 y 范围的“虚拟”箱线图中获取统计信息。
      猜你喜欢
      • 1970-01-01
      • 2013-03-28
      • 1970-01-01
      • 2018-10-22
      • 2013-10-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-09
      相关资源
      最近更新 更多