通过facet_wrap重新排序ggplot barplot x-axis

时间:2017-11-30 18:21:33

标签: r ggplot2 dplyr

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

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个想法,所以排序由第一组设置。

enter image description here

我希望拥有的是两个方面的思想顺序,与每个群体无关。如何在dplyr字符串中执行此操作?我错过了一些简单的东西吗?

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

1 个答案:

答案 0 :(得分:2)

这是一种解决方法:

数据:

# 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

enter image description here

注意:

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