【问题标题】:Creating Stacked Bar Chart With one Variable for each Bar, using melt, and ggplot使用melt和ggplot为每个条创建一个变量的堆叠条形图
【发布时间】:2018-05-24 19:05:00
【问题描述】:

这个问题与我昨天发布的问题提出了不同的观点,并有更好的描述,所以我希望你的理解。我有以下数据:

Data <- data.frame(LMX = c(1.92, 2.33, 3.52, 5.34, 6.07, 4.23, 3.45, 5.64), Thriving = c(4.33, 6.54, 6.13, 4.85, 4.26, 6.32, 5.63, 4.55), Wellbeing = c(1.92, 2.33, 3.52, 2.34, 4.07, 3.23, 3.45, 4.64))
rownames(Data) <- 1:8

现在,我的目标是生成一个翻转条形图,它为每个变量显示一个条形图,所有条形图的总和为 100%,并根据值进行划分 - 黄色表示从 0 到 1.99 的所有值,橙色表示从 2 到 3.99 的所有值,红色代表 4 到 5.99 的所有值,绿色代表 6 到 7 的所有值。 更准确地说,我正在寻找这样的东西。:

现在,我尝试了以下代码:

Data_A <- melt(cbind(Data, ind = rownames(Data)), id.vars = c('ind'))

ggplot(Data_A, aes(x = variable, y = value, fill = factor(value))) + 
geom_bar(position = "fill", stat = "identity") + 
scale_y_continuous(labels = percent_format())  + 
coord_flip()

不幸的是,我不知道如何对上面提到的那些类别中的值进行分组。更重要的是,使用这段代码,这些值甚至没有按正确的顺序排列,从低到高。

您能否给我一些建议如何获得如上所示的图片?

此外,还有一个问题:这 8 个人中的每一个人都属于两个群体之一,我想根据这两个群体来区分价值观。但是,在我的代码中包含这个附加变量只会将它与其他变量融合在一起。所以我也没有看到任何方法来解释这里的组,例如使用 facet_grid() 添加组标识符。你在这里也有什么建议吗? 我应该使用完全不同的方法/代码吗?

【问题讨论】:

    标签: r ggplot2 melt geom-bar stacked-chart


    【解决方案1】:

    这是您要寻找的关于第一部分的内容吗? (我建议你改变颜色以防止癫痫发作。)

    Data %>%
      mutate_all(cut, c(0, 2, 4, 6, 7), right = F, ) %>% 
      gather(key = "variable", value= "value") %>% 
      ggplot(aes(x = variable, fill = value)) + 
      geom_bar(position = position_fill(reverse = TRUE)) +
      coord_flip() +
      scale_fill_manual(values=c("yellow", "orange", "red", "green"))
    

    对于第二部分,一个可重现的示例会很有用,但您可以添加一个“组”变量(在gatherggplot 之间)并使用facet_gridfacet_wrap

    --- 在关于组的信息后在下面编辑---

    DataG[Data_IlA$G1_ID == 2] 中缺少列选择,并且变量名称与 DataG 中的名称不同,因此无法创建 DataG_1。

    以下建议之一是否可以制作出您想要的图?

    DataG %>%
      gather(key = "variable", value = "value", -Group_ID) %>%
      mutate(value = cut(value, c(0, 1.99, 3.99, 5.99, 7))) %>%
      ggplot(aes(x = variable, fill = value)) +
      geom_bar(position = position_fill(reverse = TRUE)) +
      scale_y_continuous(labels = scales::percent) +
      coord_flip() +
      scale_fill_manual(values=c("#19557E","#6E3B60", "#EA916A", "#EFC76C")) +
      theme(panel.background = element_blank()) +
      xlab("") + ylab("") +
      facet_grid(Group_ID ~ .)
    

    DataG %>%
      gather(key = "variable", value = "value", -Group_ID) %>%
      mutate(value = cut(value, c(0, 1.99, 3.99, 5.99, 7))) %>%
      ggplot(aes(x = Group_ID, fill = value)) +
      geom_bar(position = position_fill(reverse = TRUE)) +
      scale_x_discrete(limits = c("Group 1","Group 2")) +
      scale_y_continuous(labels = scales::percent) +
      coord_flip() +
      scale_fill_manual(values=c("#19557E","#6E3B60", "#EA916A", "#EFC76C")) +
      theme(panel.background = element_blank()) +
      xlab("") + ylab("") +
      facet_grid(variable ~ .)
    

    --- 在对群组发表评论后在下方编辑---

    如果您需要更改任何变量的类别,最简单的方法可能是在调用ggplot之前这样做:

    DataG %>%
      mutate(Group_ID = case_when(
        Group_ID == 1 ~ "1st group's name",
        Group_ID == 2 ~ "2nd group's name"
      )) %>% 
      gather(key = "variable", value = "value", -Group_ID) %>%
      mutate(value = cut(value, c(0, 1.99, 3.99, 5.99, 7))) %>%
      ggplot(aes(x = variable, fill = value)) +
      geom_bar(position = position_fill(reverse = TRUE)) +
      scale_y_continuous(labels = scales::percent) +
      coord_flip() +
      scale_fill_manual(values=c("#19557E","#6E3B60", "#EA916A", "#EFC76C")) +
      theme(panel.background = element_blank()) +
      xlab("") + ylab("") +
      facet_grid(Group_ID ~ .)
    

    【讨论】:

    • 感谢您的回答,非常有帮助!我在下面自己添加了一个答案,其中我为问题的第二部分提供了一个可重复的示例-也许您在这里也有想法? (是的,改变颜色确实是必要的;))
    • 这正是我想要的,谢谢!!最后一件事:我想为组指定特定名称 - 对于第二个图形,我发现了如何做到这一点“... scale_x_discrete(limits = c("Group 1","Group 2"), labels = c(" A 部门”、“B 部门”))……”。但是,对于第一个图形,我失败了。我试图在 face_grid() 的 labeller 下添加它,但它不起作用:“... facet_grid(Group_ID ~ ., labeller = labeller("1" = as_labeller("Department A"), "2" = as_labeller (“B 部门”)))……”。您在这里也有想法/提议吗??
    • 有几种方法可以做到这一点,但我建议您在调用 ggplot 之前更改变量的值(参见编辑后的答案)。
    • 又一次成功了!非常感谢您的出色帮助 - 我希望我拥有相同水平的知识......
    • 谢谢,但我在这里的知识仅限于您可以轻松学习的几个 tidyverse 技巧。很高兴我能提供帮助;如果您的问题得到解决,您可以接受这个答案。
    【解决方案2】:

    您可以使用melt。这是否符合您的要求?

    ggplot(Data_A, aes(x = variable, y = value, fill = cut(value,breaks = c(0,2,4,6,7)))) + 
      geom_bar(position = "fill", stat = "identity") + 
      scale_y_continuous(labels = percent_format())  +
      scale_fill_manual(name="answer",values=c("yellow","orange","red","green")) +
      coord_flip()
    

    【讨论】:

    • 非常感谢您的回答,我终于使用了收集而不是熔化,但我想它们在这里同样有用。我自己在下面添加了一个关于区分受访者所属群体的答案,并感谢您在此处提供的任何帮助。
    【解决方案3】:

    要对multiple numeric fills 进行分组,您必须使用cut() 函数。它会将数字分组为您想要的值,从-Inf+Inf。然后可以使用scale_fill_manual() 对这些组进行专门着色。

    使用此代码:

    ggplot(Data_A, aes(x = variable, y = value)) +
      scale_y_continuous(labels = percent_format())+coord_flip()+ 
      geom_bar(position = "fill", stat = "identity",aes(fill=cut(value,c(0,2,4,6,7))))+
      scale_fill_manual(values=c("#F8F668","#F8BA5B","#F66053","#82F653"))+
      labs(fill="")+theme(panel.background = element_blank())
    

    该图的输出如下所示:

    希望这会有所帮助!

    【讨论】:

    • 非常感谢,非常有用的答案!我在下面的附加答案中添加了代码。您知道如何制作两个图表,每个图表对应受访者所属的组吗?
    【解决方案4】:

    感谢非常有帮助的答案,我能够将以下代码放在一起回答我最初提出的第一个问题:

    DataG <- data.frame(LMX = c(1.92, 2.33, 3.52, 5.34, 6.07, 4.23, 3.45, 5.64), Thriving = c(4.33, 6.54, 6.13, 4.85, 4.26, 6.32, 5.63, 4.55), Wellbeing = c(1.92, 2.33, 3.52, 2.34, 4.07, 3.23, 3.45, 4.64) , Group_ID = c(1, 2, 1, 2, 2, 2, 1, 1))
    rownames <- 1:8
    
    
    DataG[Data_IlA$G1_ID == 2] %>%
      select("Leader-Member-Exchange" = LMX, "Thriving" = Thriving, "Wellbeing" = Wellbeing) %>% 
      na.omit -> DataG_1
    
    DataG_1 %>%
      mutate_all(cut, c(0, 1.99, 3.99, 5.99, 7) ) %>%
      gather(key = "variable", value = "value") %>%
      ggplot(aes(x = variable, fill = value)) +
      geom_bar(position = position_fill(reverse = TRUE)) +
      scale_y_continuous(labels = percent_format()) +
      coord_flip() +
      scale_fill_manual(values=c("#19557E","#6E3B60", "#EA916A", "#EFC76C")) +
      theme(panel.background = element_blank())
    

    现在,关于我最初提出的第二个问题: 正如您在上面的源数据 (DataG) 中看到的,我添加了另一个变量 G1_ID,它是一个组标识符 - 每个受访者都属于两个组中的一个。 我想为每个组的值显示单独的条形图。 正如您在代码中看到的那样,我在源数据 DataG 后面添加了“[Data_IlA$G1_ID == 2]”,以便让 R 只考虑属于第 2 组的观察值。但是,这个添加到代码根本不会改变任何东西。 这是为什么?我还可以使用哪些其他代码来区分这两个组?我应该改用 Facet_grid() 吗?

    非常感谢您的 cmets,

    安德烈亚斯

    【讨论】:

      猜你喜欢
      • 2021-07-31
      • 2011-02-06
      • 2018-04-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-06
      • 1970-01-01
      相关资源
      最近更新 更多