在每个 class、ggplot 的中间注释百分比堆叠条形图

Annotate Percent stacked barchart in the middle of each class, ggplot

我有这个数据:

structure(list(filter = structure(c(1L, 1L, 1L, 1L, 2L, 2L, 2L, 
2L, 3L, 3L, 3L, 3L, 4L, 4L, 4L, 4L), .Label = c("no filtering, (523)", 
"p3 <= 2 mm, (421)", "p3 <= 5 mm, (384)", "p3 <= 10 mm, (337)"
), class = "factor"), conti = c("False Negative", "False Positive", 
"True Negative", "True Positive", "False Negative", "False Positive", 
"True Negative", "True Positive", "False Negative", "False Positive", 
"True Negative", "True Positive", "False Negative", "False Positive", 
"True Negative", "True Positive"), n = c(26L, 476L, 47L, 497L, 
15L, 173L, 248L, 406L, 23L, 102L, 282L, 361L, 33L, 68L, 269L, 
304L), share = c(0.0248565965583174, 0.455066921606119, 0.0449330783938815, 
0.475143403441683, 0.0178147268408551, 0.205463182897862, 0.294536817102138, 
0.482185273159145, 0.0299479166666667, 0.1328125, 0.3671875, 
0.470052083333333, 0.0489614243323442, 0.100890207715134, 0.399109792284866, 
0.451038575667656)), row.names = c(NA, -16L), groups = structure(list(
    filter = structure(1:4, .Label = c("no filtering, (523)", 
    "p3 <= 2 mm, (421)", "p3 <= 5 mm, (384)", "p3 <= 10 mm, (337)"
    ), class = "factor"), .rows = structure(list(1:4, 5:8, 9:12, 
        13:16), ptype = integer(0), class = c("vctrs_list_of", 
    "vctrs_vctr", "list"))), row.names = c(NA, 4L), class = c("tbl_df", 
"tbl", "data.frame"), .drop = TRUE), class = c("grouped_df", 
"tbl_df", "tbl", "data.frame"))

使用以下代码生成此“百分比堆叠条形图”:

ggplot(contis) +
  geom_bar(
    aes(
      y = filter,
      x = n,
      fill = conti
    ),
    stat = "identity",
    position = "fill"
  ) +
  geom_text(
    aes(
      x = share,
      y = filter,
      label = round(share, 2)
    )
  )

现在注释完全错误,我有点不知道如何实现这一点。 我希望每个 class 的份额大致在中间(对于非常小的是不可能的)。

要向条形图添加标签,您必须设置正确的 position 参数,因为 geom_bargeom_col 默认使用 position="stack"geom_text使用 position="identity":

因此,要堆叠标签,请将 position = position_stack() 添加到 geom_text。此外,要将标签放置在条形中间,请使用 vjust = .5。最后,您必须告诉 ggplot 关于分组的信息,在您的情况下,分组是映射到 fill 上的变量。为此添加 group=conti:

library(ggplot2)
ggplot(contis) +
  geom_bar(
    aes(
      y = filter,
      x = n,
      fill = conti
    ),
    stat = "identity",
    position = "fill"
  ) +
  geom_text(
    aes(
      x = share,
      y = filter,
      label = round(share, 2),
      group = conti,
    ),
    position = position_stack(vjust = .5)
  )

但是,您可以通过在 ggplot() 中设置美学来稍微简化您的代码,如下所示:

ggplot(contis, aes(share, filter, fill = conti)) +
  geom_col() +
  geom_text(aes(label = round(share, 2)), position = position_stack(vjust = .5))