ggplot2 boxplot 中位数未按预期绘制

ggplot2 boxplot medians aren't plotting as expected

所以,我有一个相当大的数据集 (Dropbox: csv file),我正在尝试使用 geom_boxplot 进行绘制。以下产生了一个看似合理的情节:

require(reshape2)
require(ggplot2)
require(scales)
require(grid)
require(gridExtra)

df <- read.csv("\Downloads\boxplot.csv", na.strings = "*")
df$year <- factor(df$year, levels = c(2010,2011,2012,2013,2014), labels = c(2010,2011,2012,2013,2014))

d <- ggplot(data = df, aes(x = year, y = value)) +
    geom_boxplot(aes(fill = station)) + 
    facet_grid(station~.) +
    scale_y_continuous(limits = c(0, 15)) + 
    theme(legend.position = "none"))
d

然而,当你深入挖掘时,问题就会悄悄出现,这让我很害怕。当我用它们的值标记箱线图中位数时,结果如下。

df.m <- aggregate(value~year+station, data = df, FUN = function(x) median(x))
d <- d + geom_text(data = df.m, aes(x = year, y = value, label = value)) 
d

geom_boxplot 绘制的中位数根本不是中位数。标签绘制在正确的 y 轴值处,但箱线图的中间铰链绝对不在中位数。我已经被这个难住了好几天了。

这是什么原因?如何使用正确的中位数制作这种类型的显示器?如何调试或诊断此图?

这道题的答案就在scale_y_continuous的应用中。 ggplot2 将按以下顺序执行操作:

  1. 缩放变换
  2. 统计计算
  3. 坐标变换

在这种情况下,因为调用了比例转换,所以 ggplot2 排除了箱线图铰链统计计算的比例限制之外的数据。但是,由 aggregate 函数计算并在 geom_text 指令中使用的中位数将使用整个数据集。这可能会导致不同的中间铰链和文本标签。

解决方案是省略 scale_y_continuous 指令,而是使用:

d <- ggplot(data = df, aes(x = year, y = value)) +
geom_boxplot(aes(fill = station)) + 
facet_grid(station~.) +
theme(legend.position = "none")) +
coord_cartesian(y = c(0,15))

这允许 ggplot2 使用整个数据集计算箱线图铰链统计数据,同时限制图形的绘图大小。