【问题标题】:Reorder ggplot barplot x-axis by facet_wrap通过 facet_wrap 重新排序 ggplot barplot x 轴
【发布时间】:2018-05-14 18:40:24
【问题描述】:

假设我有一个示例数据框:

frame <- 
    data.frame(group = c(rep(1, 3), rep(2, 3)), 
               idea = c(1, 2, 3, 1, 2, 4), 
               value = c(10000, 5000, 50, 5000, 7500, 100), 
               level = sample(c("rough", "detailed"), 6, TRUE))

我想要一个值的条形图,其中包含按其值排序的组中的每个想法。我可以这样靠近

library(dplyr)
library(ggplot2)

top_ideas <- 
    frame %>%
    group_by(group) %>%
    arrange(group, desc(value))

frame %>%    
    group_by(group) %>%
    mutate(idea = idea %>% factor(levels = top_ideas$idea)) %>%
    ggplot(aes_string(x = "idea", y = "value", fill = "level")) +
    geom_bar(stat = "identity") +
    theme(legend.position = "bottom", 
          axis.text.x = element_text(angle = 45, vjust = 1, hjust = 1)) +
    facet_wrap(~group, scales = "free")

最后dplyr 行中的变异是根据它们在上面的top_ideas 数据框中的顺序设置因子水平。不幸的是,由于第 1 组和第 2 组共享想法 1 和 2,因此排序由第一组设置。

我想要的是独立于每个组的两个方面的想法排序。我怎样才能在 dplyr 字符串中做到这一点?我错过了一些简单的东西吗?

我应该注意,这是示例数据。实际数据要大得多,包含更多的群体和更多的共享想法。

【问题讨论】:

    标签: r ggplot2 dplyr


    【解决方案1】:

    这里有一个解决方法:

    数据:

    # setting seed to make solution reproducible
    set.seed(123)
    frame <- 
      data.frame(group = c(rep(1, 3), rep(2, 3)), 
                 idea = c(1, 2, 3, 1, 2, 4), 
                 value = c(10000, 5000, 50, 5000, 7500, 100), 
                 level = sample(c("rough", "detailed"), 6, TRUE))
    

    代码:

    library(dplyr)
    library(tidyr)
    library(ggplot2)
    
    top_ideas <- 
      frame %>%
      group_by(group) %>%
      arrange(group, desc(value)) %>%
      unite("grp_idea", group, idea, sep = "_", remove = FALSE) %>%
      data.frame() %>%
      mutate(grp_idea = factor(grp_idea, levels = grp_idea))
    
    top_ideas %>%    
      group_by(group) %>%
      ggplot(aes(x = grp_idea, y = value, fill = level)) +
      geom_bar(stat = "identity") +
      theme(legend.position = "bottom", 
            axis.text.x = element_text(angle = 45, vjust = 1, hjust = 1)) +
      facet_wrap(~group, scales = "free") +
      xlab("idea") +
      scale_x_discrete(breaks = top_ideas$grp_idea,
                       labels = top_ideas$idea)
    

    结果:

    > top_ideas
      grp_idea group idea value    level
    1      1_1     1    1 10000    rough
    2      1_2     1    2  5000 detailed
    3      1_3     1    3    50    rough
    4      2_2     2    2  7500 detailed
    5      2_1     2    1  5000 detailed
    6      2_4     2    4   100    rough
    

    注意:

    基本上我所做的是将groupidea 变量粘贴在一起,将新变量grp_idea 转换为具有所需水平的因子,并将其用作x 轴而不是原来的@ 987654329@ 专栏。这确保了每个方面中级别的顺序不会受到其他方面的影响,因为它们不再共享相同的级别。然后很容易用xlabscale_x_discrete 重新标记x 轴标题和刻度标签。

    【讨论】:

    • 很好,直接的解决方法。另外,感谢您向我介绍unite
    • @Steven Opps,我忘了加library(tidyr)unite 来自 tidyr。还要检查separateextract 将一列分成两列或多列。
    • 没问题。我刚刚?unite 看到它来自tidyr。不过,感谢其他 fxs 的提示。这会很有帮助。
    猜你喜欢
    • 2021-07-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-24
    • 2014-07-02
    相关资源
    最近更新 更多