【问题标题】:Reorder bars of ggplot2 plot based on the value of a level of a factor根据因子水平的值对 ggplot2 图的条形重新排序
【发布时间】:2017-06-14 04:48:04
【问题描述】:

我有数据框df,有 46 行和 3 列。

我正在尝试通过program_ID 变量创建youth_activity_rc 变量值的图,例如此代码/图。 . .

library(ggplot2)
ggplot(df, aes(x = program_name, y = total_minutes_p, group = youth_activity_rc, fill = youth_activity_rc)) +
    geom_col(position = position_stack(reverse = T)) +
    coord_flip()

。 . .但program_ID 变量根据youth_activity_rc 变量的Not Focused 因子水平重新排序:

有许多问题演示了如何基于单个变量(即this question)来执行此操作,但我找不到基于与因子水平相关的值来执行此操作的问题(在这种情况下为Not Focused);这看起来很简单,但至少基于其他答案中推荐的解决方案(即使用stats::reorder() 或dplyr::arrange()),事实并非如此。

数据在这里:

df <- structure(list(program_ID = structure(c(1L, 1L, 1L, 1L, 1L, 2L, 
2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 4L, 4L, 4L, 4L, 4L, 4L, 5L, 5L, 
5L, 5L, 5L, 6L, 6L, 6L, 6L, 7L, 7L, 7L, 7L, 7L, 8L, 8L, 8L, 8L, 
8L, 8L, 9L, 9L, 9L, 9L, 9L, 9L), .Label = c("1", "2", "4", "5", 
"6", "7", "8", "9", "10"), class = "factor"), youth_activity_rc = structure(c(2L, 
6L, 5L, 1L, 3L, 2L, 6L, 1L, 3L, 2L, 6L, 5L, 1L, 3L, 2L, 6L, 4L, 
5L, 1L, 3L, 2L, 6L, 5L, 1L, 3L, 2L, 6L, 1L, 3L, 2L, 6L, 4L, 1L, 
3L, 2L, 6L, 4L, 5L, 1L, 3L, 2L, 6L, 4L, 5L, 1L, 3L), .Label = c("Not Focused", 
"Basic Skills Activity", "Program Staff Led", "Field Trip Speaker", 
"Lab Activity", "Creating Product"), class = "factor"), total_minutes_p = c(0.248, 
0.116, 0.075, 0.458, 0.103, 0.466, 0.015, 0.202, 0.317, 0.248, 
0.263, 0.006, 0.372, 0.111, 0.183, 0.172, 0.088, 0.048, 0.305, 
0.203, 0.157, 0.066, 0.079, 0.592, 0.106, 0.128, 0.423, 0.423, 
0.026, 0.176, 0.233, 0.125, 0.426, 0.04, 0.164, 0.188, 0.046, 
0.007, 0.524, 0.072, 0.163, 0.112, 0.013, 0.021, 0.567, 0.124
)), .Names = c("program_ID", "youth_activity_rc", "total_minutes_p"
), row.names = c(NA, -46L), vars = "program_ID", labels = structure(list(
    program_ID = c(1, 2, 4, 5, 6, 7, 8, 9, 10)), .Names = "program_ID", row.names = c(NA, 
-9L), class = "data.frame", vars = "program_ID", drop = TRUE), indices = list(
    0:4, 5:8, 9:13, 14:19, 20:24, 25:28, 29:33, 34:39, 40:45), drop = TRUE, group_sizes = c(5L, 
4L, 5L, 6L, 5L, 4L, 5L, 6L, 6L), biggest_group_size = 6L, class = c("grouped_df", 
"tbl_df", "tbl", "data.frame"))

【问题讨论】:

    标签: r ggplot2


    【解决方案1】:

    通过youth_activity_rc 和total_minutes_p 对您的数据集进行排序,然后在绘图之前使用包forcats 中的fct_inorder 是一种选择。

    fct_inorder 按照它们在数据集中出现的顺序设置因子的水平,这就是为什么需要对数据集进行排序以按所需顺序获得program_ID 的水平。

    library(dplyr)
    library(forcats)
    
    df2 = df %>% 
        ungroup() %>%
        arrange(youth_activity_rc, total_minutes_p) %>%
        mutate(program_ID = fct_inorder(program_ID) )
    

    还有剧情:

    ggplot(df2, aes(x = program_ID, y = total_minutes_p, 
                 group = youth_activity_rc, 
                 fill = youth_activity_rc)) +
        geom_col(position = position_stack(reverse = TRUE)) +
        coord_flip()
    

    使用fct_relevel 而arrangeing 将您想要作为订单基础的因素的水平设置为第一水平。例如,如果您想要在“Creating Product”而不是“Not Focused”中按total_minutes_p 排序的图表:

    df2 = df %>% 
        ungroup() %>%
        arrange(fct_relevel(youth_activity_rc, "Creating Product"), total_minutes_p) %>%
        mutate(program_ID = fct_inorder(program_ID) )
    

    【讨论】:

    • 如果Not Focused 不是youth_activity_rc 的第一级,除了将其设置为第一级之外,还有什么直接的方法吗?
    • 我不知道,但如果您不想永久更改订购因子的水平,可以在arrange 内完成。见编辑。
    【解决方案2】:

    类似于 aosmith 的方法,但不使用 forcats/dplyr 进行数据操作。您可以获取所需子集内 的顺序,然后重构您的数据以具有该顺序的级别。比如:

    levs <- df[which(df$youth_activity_rc == "Not Focused"), ] #Get the "Not focused" group
    order <- order(levs[,"total_minutes_p"]) #Order within your selected group
    
    df$program_ID_2 <- factor(df$program_ID, levels = levs[order, "program_ID"])
    
    ggplot(df, aes(x = program_ID_2, y = total_minutes_p, 
                    group = youth_activity_rc, 
                    fill = youth_activity_rc)) +
      geom_col(position = position_stack(reverse = TRUE)) +
      coord_flip()
    

    请注意,我创建了一个名为 program_ID_2 的新变量,但您不必这样做

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-14
      • 2017-08-20
      • 1970-01-01
      • 2021-10-02
      相关资源
      最近更新 更多