【问题标题】:ggplot2 barplots with errorbars when using stacked bars使用堆叠条时带有误差条的 ggplot2 条形图
【发布时间】:2021-01-20 08:16:08
【问题描述】:

我正在尝试生成一个带有误差条的堆叠条形图,该条形图代表每个条形的总可变性。我不想使用闪避的条形图,因为每个条形图有 >10 个类别。

下面我有一些可重现示例的示例数据:

scenario = c('A','A','A','A')
strategy = c('A','A','A','A')
decile = c(0,0,10,10)
asset = c('A','B','A','B')
lower = c(10,20,10, 15)
mean = c(30,50,60, 70)
upper = c(70,90,86,90)
data = data.frame(scenario, strategy, decile, asset, lower, mean, upper)

一旦我们有了data df,我们就可以使用 ggplot2 来创建一个堆叠条:

ggplot(wide, aes(x=decile, y=mean, fill=asset)) + 
  geom_bar(stat="identity") +
  facet_grid(strategy~scenario) +
  geom_errorbar(aes(ymin = lower, ymax = upper), width = 0.25)

但是,产生的误差条是针对每个堆叠条的每个单独组件:

感谢我为 df 的每一行提供 lowermeanupper 的结果,但即使我将这些按十分位数相加,我也没有在每行的顶部得到我想要的错误栏条形堆栈。

什么是正确的 ggplot2 代码,或者,启用此功能的正确数据结构是什么?

【问题讨论】:

  • 也许你正在寻找这个:ggplot(data, aes(x=factor(decile), y=mean, fill=asset,group=scenario)) + geom_bar(stat="identity") + facet_grid(strategy~scenario) + geom_errorbar(aes(ymin = lower, ymax = upper), width = 0.25)

标签: r ggplot2 bar-chart errorbar


【解决方案1】:

如果您只希望每个十分位数有一个误差线,您应该聚合这些值,以便这样的评估之间没有差异:

library(ggplot2)
library(dplyr)
#Code
data %>% group_by(scenario,decile) %>% 
  mutate(nlower=mean(lower),nupper=mean(upper)) %>%
  ggplot(aes(x=factor(decile), y=mean, fill=asset,group=scenario)) + 
  geom_bar(stat="identity") +
  facet_grid(strategy~scenario) +
  geom_errorbar(aes(ymin = nlower, ymax = nupper), width = 0.25)

输出:

使用资产是另一回事,因为它会考虑每个类,因为每个类都有不同的值:

#Code 2
data %>%
  ggplot(aes(x=factor(decile), y=mean, fill=asset,group=scenario)) + 
  geom_bar(stat="identity") +
  facet_grid(strategy~scenario) +
  geom_errorbar(aes(ymin = lower, ymax = upper), width = 0.25)

输出:

在上一个版本中,每个资产都有自己的误差线,但如果您想在全局范围内查看错误,您应该使用聚合限制的方法,就像使用平均值或您希望的其他度量一样。

【讨论】:

    【解决方案2】:

    我认为你意识到你需要操纵你的数据而不是你的情节是正确的。 position_stack 不能真的出现在误差条上,因此您需要重新计算误差条的平均值、上限和下限。本质上,这意味着获取平均值的累积和,并相应地移动上限和下限。您可以在 dplyr 管道中执行此操作。

    请注意,我认为您还需要在错误栏上添加 position_dodge,因为即使适当移动它们的范围也会重叠,这将使它们更难从视觉上解释:

    library(ggplot2)
    library(dplyr)
    
    data %>% 
      mutate(lower = lower - mean, upper = upper - mean) %>%
      group_by(decile) %>% 
      arrange(rev(asset), by.group = TRUE) %>%
      mutate(mean2 = cumsum(mean), lower = lower + mean2, upper = upper + mean2) %>%
      ggplot(aes(x = decile, y = mean, fill = asset)) + 
      geom_bar(stat = "identity") +
      facet_grid(strategy ~ scenario) +
      geom_errorbar(aes(y = mean2, ymin = lower, ymax = upper), width = 2,
                    position = position_dodge(width = 2)) +
      geom_point(aes(y = mean2), position = position_dodge(width = 2))
    

    【讨论】: