R -添加点后更新箱线图轴范围

l2osamch  于 2023-02-06  发布在  其他
关注(0)|答案(1)|浏览(191)

我有一个箱形图,将约60000个浊度数据点总结为四分位数、中位数、须线,有时还包括离群值。通常,一些离群值太高,以至于整个图在底部被压缩,因此我选择忽略离群值。但是,我也将平均值作为点添加到图中。我希望这些都能被绘制出来。问题是箱线图的y轴不能调整到增加的平均点,所以当平均值远远高于箱线图时,它们只是被绘制在图表窗口之外(参见2020年的X点,但2021年或2022年没有)。通常,使用此参数时,平均值将介于须端和最极端异常值之间。这是正常的,并且在数据中是预期的。

我已经尝试过捕获箱线图y轴范围以与平均值进行比较,然后在需要时设置ylim,但我就是不知道如何检索这些轴范围。
我的代码只是箱线图(...)点(...)和工程至于绘制点。只是不调整y轴。
问题1:是否无法使用新的点数据重新绘制箱线图?我认为这是R图中的标准。问题2:如果没有,如何动态调整y轴范围?

wnavrhmk

wnavrhmk1#

让我们试着用一些模拟数据来展示这个问题的一个具体例子:

set.seed(1)

df <- data.frame(y = c(rexp(99), 150), x = rep(c("A", "B"), each = 50))

在这里,B组只有一个异常值150,尽管大多数值都要低几个数量级,这意味着如果我们试图画一个箱形图,图的底部的箱形会被压扁:

boxplot(y ~ x, data = df, col = "lightblue")

如果我们移除离群值,则箱形图绘制得很好:

boxplot(y ~ x, data = df, col = "lightblue", outline = FALSE)

当我们想添加一个点来表示每个箱线图的平均值时,问题就来了,因为“B”的平均值超出了图的界限。让我们计算并绘制平均值:

mean_vals <- sapply(split(df$y, df$x), mean)
mean_vals
#>         A         B 
#> 0.9840417 4.0703334

boxplot(y ~ x, data = df, col = "lightblue", outline = FALSE)
points(1:2, mean_vals, cex = 2, pch = 16, col = "red")

“B”的均值缺失,因为它位于图的上限之上。
这里的秘密是使用boxplot.stats来获得须线的极限。通过将均值向量连接到统计向量并获得其range,我们可以将图极限精确地设置在需要的位置:

y_limits <- range(c(boxplot.stats(df$y)$stats, mean_vals))

现在我们将这些限制应用于新的箱线图,并使用以下点绘制:

boxplot(y ~ x, data = df, outline = FALSE, ylim = y_limits, col = "lightblue")
points(1:2, mean_vals, cex = 2, pch = 16, col = "red")

为了进行比较,您可以在ggplot中这样做:

library(ggplot2)

ggplot(df, aes(x, y)) +
  geom_boxplot(fill = "lightblue", outlier.shape = NA) +
  geom_point(size = 3, color = "red", stat = "summary", fun = mean) +
  coord_cartesian(ylim = range(c(range(c(boxplot.stats(df$y)$stats, 
                                         mean_vals))))) +
  theme_classic(base_size = 16)

创建于2023年2月5日,使用reprex v2.0.2

相关问题