根据子类别重新排序堆叠的 ggplot2 beom_bar

Reorder stacked ggplot2 beom_bar according to sub-category

上下文

下面的数据集包含了一个学校的院系有多少学生badalrightgood

students <- data_frame(
    department = factor(c("Maths", "Physics", "Economics")),
    bad = c(15, 20, 8),
    alright = c(10, 22, 17),
    good = c(8, 12, 5)
)

我整理了数据集,然后用它制作了一个堆叠条形图,以可视化每个类别和每个部门的学生人数:

tidy_students <- students %>% 
    gather(key = "student_quality", value = "number", -department)

ggplot(data = tidy_students, aes(x = department, y = number, fill = student_quality)) +
    geom_bar(stat = "identity") +
    coord_flip()

我的目标

我希望能够根据学生的子类别对条形图重新排序。例如,如果我想根据好学生的数量 以降序重新排列条形图 ,那么顶部的条形图将用于物理系,然后是经济学条形图,最后数学栏。

我正在处理的实际数据有更多的类别(部门)和子类别(学生质量),我希望能够根据任何子类别对条形图重新排序。

我怎样才能做到这一点?非常感谢您的帮助。

条形是根据因素的水平排序的。在您的情况下,这些是

levels(tidy_students$department)
## [1] "Economics" "Maths"     "Physics"

并且条形图是从底部开始按该顺序绘制的。要更改此设置,您只需更改因子中级别的顺序。例如,您可以明确指定所需的顺序:

tidy_students$department <- factor(tidy_students$department,
                                   levels = c("Maths", "Economics", "Physics"))

因此,您的问题基本上可以归结为生成一个向量,其中包含所需顺序的级别。

我将向您展示如何针对您在问题中提出的示例执行此操作:根据好学生的数量按降序排列条形图。由于条形图是从底部开始绘制的,因此我必须创建完全相反的顺序:

library(dplyr)
ordered <- filter(tidy_students, student_quality == "alright") %>%
            arrange(number)
tidy_students$department <- factor(tidy_students$department, levels = ordered$department)

ggplot(data = tidy_students, aes(x = department, y = number, fill = student_quality)) +
    geom_bar(stat = "identity") +
    coord_flip()

您也可以使用 arrange(desc(number)) 降序排序。