通过facet_wrap对ggplot barplot x轴重新排序 [英] Reorder ggplot barplot x-axis by facet_wrap
问题描述
假设我有一个示例数据帧:
Let's say I have an example data frame:
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))
我想要一个值的示意图,其中每个创意都按其价值排序。我可以像这样
I'd like a barplot of values with each idea within a group ordered by it's value. I can get close like this
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组共享,因此排序由第一个组设置。
The mutate in the final dplyr
line is setting the factor levels according to their ordering in the top_ideas
dataframe above that. Unfortunately, because the idea nos 1 and 2 are shared by both groups 1 and 2, the ordering is set by the first group.
我想拥有的是在两个方面中独立于每个小组的思想排序。如何在 dplyr
字符串中做到这一点?我想念一些简单的东西吗?
What I'd like to have is the ordering of ideas in both facets independent of each group. How can I do that in a dplyr
string? Am I missing something simple?
我应该注意,这是示例数据。实际数据要大得多,并且包含更多的组和共享的更多想法。
I should note that this is example data. The actual data is much larger and encompasses more groups and more ideas that are shared.
推荐答案
这是一种解决方法:
数据:
# 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
< a href = https://i.stack.imgur.com/KfJUA.png rel = nofollow noreferrer>
注意:
基本上我要做的是将 group
和 idea
变量粘贴在一起,转换新的变量 grp_idea
到具有所需水平的因子,并将其用作x轴,而不是原始的 idea
列。这样可以确保每个构面中的层顺序不会受到其他构面的影响,因为它们不再共享相同的层。这样很容易用 xlab
和 scale_x_discrete
重新标记x轴标题和刻度标签。
Basically what I'm doing is to paste together group
and idea
variables, convert the new variable grp_idea
to a factor with the desired levels, and use that as the x-axis instead of the original idea
column. This ensures that the ordering of levels in each facet will not be affected by other facets since they no longer share the same levels. It is then easy enough to relabel the x-axis title and tick labels with xlab
and scale_x_discrete
.
这篇关于通过facet_wrap对ggplot barplot x轴重新排序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!