箱形图晶须上的样本量

时间:2019-05-21 14:33:31

标签: r ggplot2 rstudio

我想在每个箱形图的晶须上显示“ n =(n)”。我已经弄清楚了如何使用Fivenum将这些标签放在每个框(q75)的顶部,但是我无法使它们在晶须之上工作。晶须上方更好,因为我的地块非常混乱。

在这里,我使用mtcars复制了剧情 编辑:mtcars没有明显的异常值,但是我的数据集确实有。这就是为什么标签需要位于晶须上,而不仅仅是在最高数据点上。

sidenote:我正在处理许多异常值,并希望将它们从显示中删除。 GGplot可以做到这一点,但它仍将在轴上包含离群值,这使我得到了一个非常“缩小”的图。我的解决方法包括在内。我已经使用基本的boxplot函数来计算最高的晶须,并使用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-抱歉,我不熟悉在这里发布的内容,但是我尝试了

3 个答案:

答案 0 :(得分:1)

这是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)

enter image description here

编辑

可能有一种更简洁的方法,但是我认为这可行。我为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)

enter image description here

答案 1 :(得分:0)

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

好吧,我用Alan的答案的格式弄清楚了。它需要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)))

答案 2 :(得分:0)

好好尝试一下最后的尝试。我想到了。 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))

Voila !!