使用 melt 和 ggplot 为每个条形图创建一个变量的堆积条形图

Creating Stacked Bar Chart With one Variable for each Bar, using melt, and ggplot

这个问题提出的问题和我昨天发的不一样,描述的比较好,希望大家谅解。我有以下数据:

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() 添加组标识符。你也有什么建议吗? 我应该使用完全不同的 approach/code 吗?

您在 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()

为了对 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())

下面提供了该图的输出:

希望对您有所帮助!!

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

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"))

对于第二部分,一个可重现的例子会很有用,但你可以添加一个 "group" 变量(在 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 ~ .)

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

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() 吗?

非常感谢您的意见,

安德烈亚斯