使用 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" 变量(在 gather
和 ggplot
之间)并使用 facet_grid
或facet_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() 吗?
非常感谢您的意见,
安德烈亚斯
这个问题提出的问题和我昨天发的不一样,描述的比较好,希望大家谅解。我有以下数据:
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" 变量(在 gather
和 ggplot
之间)并使用 facet_grid
或facet_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() 吗?
非常感谢您的意见,
安德烈亚斯