如何以整洁的方式重新排序因子水平?

How to reorder factor levels in a tidy way?

您好,我通常使用如下代码对 ggplot 中的条形图重新排序 或其他类型的地块。

正常情节(无序)

library(tidyverse)
iris.tr <-iris %>% group_by(Species) %>% mutate(mSW = mean(Sepal.Width)) %>%
  select(mSW,Species) %>% 
  distinct()
ggplot(iris.tr,aes(x = Species,y = mSW, color = Species)) +
  geom_point(stat = "identity")

排序因子 + 排序图

iris.tr$Species <- factor(iris.tr$Species,
                          levels = iris.tr[order(iris.tr$mSW),]$Species,
                          ordered = TRUE)
ggplot(iris.tr,aes(x = Species,y = mSW, color = Species)) + 
  geom_point(stat = "identity")

因子线对我来说非常不愉快,我想知道为什么 arrange() 或其他一些函数不能简化它。我错过了什么?

注:

这不起作用,但我想知道 tidyverse 中是否存在类似的东西。

iris.tr <-iris %>% group_by(Species) %>% mutate(mSW = mean(Sepal.Width)) %>%
  select(mSW,Species) %>% 
  distinct() %>% 
  arrange(mSW)
ggplot(iris.tr,aes(x = Species,y = mSW, color = Species)) + 
  geom_point(stat = "identity")

使用‹forcats›:

iris.tr %>%
    mutate(Species = fct_reorder(Species, mSW)) %>%
    ggplot() +
    aes(Species, mSW, color = Species) +
    geom_point()

使用基数重新排序因子:

iris.ba = iris
iris.ba$Species = with(iris.ba, reorder(Species, Sepal.Width, mean))

翻译成dplyr:

iris.tr = iris %>% mutate(Species = reorder(Species, Sepal.Width, mean))

之后,您可以继续按照您的问题进行总结和绘图。


一些评论:重新排序一个因素就是修改一个数据列。修改数据列的dplyr命令是mutatearrange 所做的只是重新排序行,这对因子的水平没有影响,因此对 ggplot 中的图例或轴的顺序没有影响。

所有因素的水平都有一个顺序。 ordered = TRUE 因子和常规因子之间的区别在于模型中对比的设置方式。 ordered = TRUE 仅当您的因子水平具有有意义的排名顺序时才应使用,例如 "Low"、"Medium"、"High",即便如此,它仅在您构建模型时才重要并且不希望默认对比度将所有内容与参考水平进行比较。

如果你正好有字符向量可以排序,例如:

iris2 <- iris %>% 
    mutate(Species = as.character(Species)) %>% 
    group_by(Species) %>% 
    mutate(mean_sepal_width = mean(Sepal.Width)) %>% 
    ungroup()

您还可以使用 forcats::as_factor 函数的行为对因子水平进行排序:

"Compared to base R, this function creates levels in the order in which they appear"

library(forcats)
iris2 %>% 
    # Change the order
    arrange(mean_sepal_width) %>%  
    # Create factor levels in the order in which they appear
    mutate(Species = as_factor(Species)) %>%
    ggplot() +
    aes(Species, Sepal.Width, color = Species) +
    geom_point()

请注意 x 轴上的物种名称不是按字母顺序排列的,而是按 mean_sepal_width 的值递增排列的。删除包含 as_factor 的行以查看差异。

如果您想手动订购等级:您也可以使用forcats使用https://forcats.tidyverse.org/reference/fct_relevel.html