【问题标题】:Percent Stacked Barplot with error bars using ggplot2使用 ggplot2 带有误差线的百分比堆积条形图
【发布时间】:2020-12-29 10:36:18
【问题描述】:

我对 R 很陌生,目前正在尝试创建一个我以前总是使用 prism 创建的百分比堆积条形图。在棱镜中,我的图表总是如下所示:

Graph created with Prism

我尝试了几种方法,但我不确定我是否正确理解 geom_bar() 函数。似乎长数据格式最适合情节:

structure(list(run = c("particle_count_run1", "particle_count_run1", 
"particle_count_run1", "particle_count_run1", "particle_count_run1", 
"particle_count_run2", "particle_count_run2", "particle_count_run2", 
"particle_count_run2", "particle_count_run2", "particle_count_run3", 
"particle_count_run3", "particle_count_run3", "particle_count_run3", 
"particle_count_run3", "particle_count_run1", "particle_count_run1", 
"particle_count_run1", "particle_count_run1", "particle_count_run1", 
"particle_count_run2", "particle_count_run2", "particle_count_run2", 
"particle_count_run2", "particle_count_run2", "particle_count_run3", 
"particle_count_run3", "particle_count_run3", "particle_count_run3", 
"particle_count_run3", "particle_count_run1", "particle_count_run1", 
"particle_count_run1", "particle_count_run1", "particle_count_run1", 
"particle_count_run2", "particle_count_run2", "particle_count_run2", 
"particle_count_run2", "particle_count_run2", "particle_count_run3", 
"particle_count_run3", "particle_count_run3", "particle_count_run3", 
"particle_count_run3"), sample = c("2K", "2K", "2K", "2K", "2K", 
"2K", "2K", "2K", "2K", "2K", "2K", "2K", "2K", "2K", "2K", "10K", 
"10K", "10K", "10K", "10K", "10K", "10K", "10K", "10K", "10K", 
"10K", "10K", "10K", "10K", "10K", "SEC", "SEC", "SEC", "SEC", 
"SEC", "SEC", "SEC", "SEC", "SEC", "SEC", "SEC", "SEC", "SEC", 
"SEC", "SEC"), size_range = structure(c(5L, 4L, 3L, 2L, 1L, 5L, 
4L, 3L, 2L, 1L, 5L, 4L, 3L, 2L, 1L, 5L, 4L, 3L, 2L, 1L, 5L, 4L, 
3L, 2L, 1L, 5L, 4L, 3L, 2L, 1L, 5L, 4L, 3L, 2L, 1L, 5L, 4L, 3L, 
2L, 1L, 5L, 4L, 3L, 2L, 1L), .Label = c("5_401:1999", "4_201:399", 
"3_151:199", "2_51:149", "1_1:49"), class = "factor"), value = c(0, 
0, 4462683, 296014836, 358497149, 0, 376611, 119940, 282521877, 
318477067, 0, 0, 799317, 242354584, 385487693, 0, 3353818, 176929269, 
964906541, 220288073, 0, 7054403, 124768386, 857429863, 207014319, 
0, 14605, 117673122, 790104146, 236717487, 7772, 894924035, 62830819, 
47826581, 3787399, 247825, 776011544, 56048930, 66062865, 3264425, 
3487, 437890092, 30162534, 33433418, 0)), row.names = c(NA, -45L
), class = c("tbl_df", "tbl", "data.frame"))

使用我第一次尝试创建百分比堆积条形图的数据:

  tmp %>%  ggplot(aes(sample, value, fill = size_range)) +
  geom_bar(position = "fill", stat = "identity")

这实际上导致了一个看起来与我想要实现的情节非常相似的情节:

R plot percent stacked

我不确定 geom_bar() 函数是否真的正确应用了我的数据: 我有

  • 3 种不同的样本:2K、10K、SEC
  • 对于每个样本,我进行了 3 次测量:particle_count_run1、particle_count_run2、particle_count_run3
  • 对于这些运行中的每一个,我都有在特定尺寸范围内测量的颗粒数量:值

由于我不知道如何将所有四个变量与 geom_bar 函数一起使用,我在 x 轴上使用 sample,在 y 轴上使用 value,并将 size_range 作为填充。

但是,我现在不确定 geom_bar 函数现在是否会自动考虑运行变量并计算平均值。如果不是,我不确定它需要哪个值。

我遇到的另一个问题是,当条形图堆叠时,我无法计算误差线。我只能用position = "dodge" 向他们展示:

tmp %>%  ggplot(aes(sample, value, 
                    group = size_range, 
                    colour = size_range, 
                    fill = size_range)) +
  stat_summary(fun = mean,
               geom = "bar",
               position = "dodge") +
  stat_summary(fun.data = mean_cl_normal,
               geom = "errorbar",
               position = "dodge")

Graph

每当我试图改变位置时,它就不再起作用了。

有人知道我做错了什么吗?我真的很难找到情节的解决方案,非常感谢任何可能的帮助:)

【问题讨论】:

  • 欢迎来到 SO!为了帮助我们帮助您,您能否通过分享您的数据样本而不是发布图片来重现您的问题?查看how to make a minimal reproducible example 只需在控制台中输入dput(tmp) 并将以structure(.... 开头的输出复制并粘贴到您的帖子中。
  • 当然!我已更改问题并复制到输出中。感谢 dput() 提示!
  • 我会检查是否有任何 ggplot 扩展可以做到这一点exts.ggplot2.tidyverse.org/gallery
  • 感谢您的链接!我浏览了它们,但我能找到的唯一一种接近的是 ggmosaic。但我也无法让它与错误栏一起工作

标签: r ggplot2 geom-bar


【解决方案1】:

这不是一个完整的答案,但我做了一些工作,并想分享我得到的东西,以防它帮助其他人让你一路获得完整的解决方案,而且评论太长了,所以这里是:

  1. 首先,在 ggplot 中堆叠误差线似乎没有得到很好的支持 (https://stackoverflow.com/a/30873811/13210554),但可以手动强制。
  2. 我相信您正在尝试对重复测量值(particle_count_run1particle_count_run2particle_count_run3)进行平均,并且您希望表示这些测量值的均值和方差。我认为这是明智之举,您需要以合适的方式安排数据来完成此任务,并且您的图表代表了您想要的结果。
  3. 最困难的部分是让ggplot2 为您提供那些堆积的误差线。在这里,我只能为您提供部分帮助...

我要在这里说明的第一点是,对于您展示的示例图,误差线只会上升,这会使图在视觉上保持干净。我同意这种堆叠图的方法,但这意味着您必须修改底部误差条计算的默认计算。

这让我想到了正确计算堆叠误差条的值的核心问题。一种选择是在ggplot 调用之外执行此操作,只需将单独的data.frame 拉入stat_summary。我试图做但到目前为止失败的选项是在stat_summary 内部使用自定义函数制作一个通用的解决方案。如果它有帮助,我想分享我到目前为止所做的事情。

我以Hmisc::smean.cl.normal的胆量为出发点:

## function (x, mult = qt((1 + conf.int)/2, n - 1), conf.int = 0.95, 
##     na.rm = TRUE) 
## {
##     if (na.rm) 
##         x <- x[!is.na(x)]
##     n <- length(x)
##     if (n < 2) 
##         return(c(Mean = mean(x), Lower = NA, Upper = NA))
##     xbar <- sum(x)/n
##     se <- sqrt(sum((x - xbar)^2)/n/(n - 1))
##     c(Mean = xbar, Lower = xbar - mult * se, Upper = xbar + mult * 
##         se)
## }

您可以将其放入stat_summary 调用并通过简单地重命名返回的变量的名称来生成相同的图(即upper 变为ymax):

df1 %>%  ggplot(aes(sample, value, fill = size_range)) +
  geom_col(position = "stack") +
  stat_summary(fun.data =
                 function (x,
                           mult = qt((1 + conf.int) / 2, n - 1),
                           conf.int = 0.95,
                           na.rm = TRUE)
                 {
                   if (na.rm)
                     x <- x[!is.na(x)]
                   n <- length(x)
                   xbar <- sum(x) / n
                   se <- sqrt(sum((x - xbar) ^ 2) / n / (n - 1))
                   c(ymin = xbar,
                     ymax = xbar + mult * se)
                 },
               geom = "errorbar",
               width = 0.5,
               color = "black"
  )

请注意,现在误差条的底部是平均值,因此它最终成为单边误差条。如果您在最后的条形图上添加黑色轮廓以覆盖底部尾部(除非您找到移除它的方法),它可能看起来最好。

所以现在的问题是,如果它从 x 轴开始,y 位置应该是每个条的位置。因此,您需要以某种方式对其进行修改,以将每个子组累积添加到该值中。然后要将其作为fill 而不是stack,您需要除以每个组的总和才能使其总数为1。可能无法在stat_summary 调用中得到它,但也许您可以使用该代码在外部执行计算。

【讨论】:

  • 非常感谢您的帮助!我实际上尝试使用您的代码并实现将颜色设置为黑色的想法,以便它适用于单侧误差线,但后来我实际上遇到了另一个问题:似乎使用 geom_col() 不适用于数据,如果我理解正确,它会绘制每个值而不是绘制平均值。这通过黑色轮廓变得可见。
  • 这个我实际上可以使用stat_summary(fun = mean, geom = "bar", position = "stack", color = "black")解决
  • 看来ggpubr 可能有解决方案 (datanovia.com/en/blog/…)
猜你喜欢
  • 1970-01-01
  • 2015-01-16
  • 1970-01-01
  • 1970-01-01
  • 2018-12-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多