【问题标题】:Order stacked ggplot2 percentage bar plot by y continuous value - repost按 y 连续值排序堆叠的 ggplot2 百分比条形图 - 重新发布
【发布时间】:2018-06-29 09:25:20
【问题描述】:

(重新发布 - 以前标记为重复,但附加的 MRE 更完整地说明了问题)

我正在尝试按该因素的百分比值对堆积百分比条形图中的一个因素进行排序,但无法弄清楚如何做到这一点。

例如在下面我希望x 中的类别按因子q 的百分比值排序。

library(tibble)
library(ggplot2)

df <- tibble(x = rep(LETTERS[1:5], 2), y = c(10,20,5,60,30,90,80,95,40,70), z = c(rep("p", 5), rep("q", 5)))

ggplot(df, aes(x = x, y = y, fill = z)) +
   geom_bar(stat = "identity", position = "fill") +
   scale_y_continuous(labels=scales::percent)

问题Reorder bars in geom_bar ggplot2 接受的解决方案使用reorder() 更改x 条的顺序,但不适用于我的情况:

ggplot(df, aes(x = reorder(x, -y), y = y, fill = z)) +
  geom_bar(stat = "identity", position = "fill") +
  scale_y_continuous(labels=scales::percent)

产生与上面完全相同的图。

我认为原因是数据格式整齐,所以 x 有多个 y 值,但我不知道如何仅将 y 的一个子集映射到 x 上。

【问题讨论】:

  • x中的级别设置为c("C", "A", "B", "E", "D")
  • 我需要以编程方式执行此操作。我的现实世界需要比玩具示例更多的案例,并且用于自动报告目的。

标签: r ggplot2


【解决方案1】:

如何首先定义级别:

df %>%
  filter(z == "q") %>%
  mutate(x = factor(x, levels = x[order(y)])) %>%
  pull(x) %>%
  levels -> x_levels

然后使用这些级别作为 ggplot 的输入:

df %>%
  mutate(x = factor(x,
                    levels = x_levels)) %>%
  ggplot(aes(x = x,
             y = y,
             fill = z)) +
  geom_bar(stat = "identity",
           position = "fill") +
  scale_y_continuous(labels = scales::percent)

另一种方法是使用两个附属功能:

在 github 上可用dgrtwo/drlib

reorder_within <- function(x, by, within, fun = mean, sep = "___", ...) {
  new_x <- paste(x, within, sep = sep)
  stats::reorder(new_x, by, FUN = fun)
}


scale_x_reordered <- function(..., sep = "___") {
  reg <- paste0(sep, ".+$")
  ggplot2::scale_x_discrete(labels = function(x) gsub(reg, "", x), ...)
}


ggplot(df, aes(x = reorder_within(x, y, 1, fun = max),
               y = y,
               fill = z)) + 
  geom_bar(stat = "identity",
           position = "fill") +
  scale_y_continuous(labels = scales::percent)+
  scale_x_reordered()

我在组内使用 1,但这些函数允许使用 more complicated sort within each facet

或:

  ggplot(df, aes(x = reorder_within(x, y, 1, fun = min),
                   y = y,
                   fill = z)) + 
      geom_bar(stat = "identity",
               position = "fill") +
      scale_y_continuous(labels = scales::percent)+
      scale_x_reordered()

【讨论】:

  • 超级好东西。 levels 方法非常简单,我会使用,但我可以看到辅助函数可以提供更多功能。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-10-14
  • 2018-12-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-29
  • 2018-01-21
相关资源
最近更新 更多