ggplot2:在每组的堆叠条形图中显示相对百分比
ggplot2: show relative % in a stacked barplot per group
我正在尝试为每个组绘制一个基本条形图。
由于值非常大,我想显示 对于每个柱状图 (即组),柱状图 中每个组的 % .
我设法显示了总数的百分比,但这不是我所期望的:在每个栏中,我希望 % 的总和等于 100%。
有没有不改变数据帧的简单方法?
(DF <- data.frame( year = rep(2015:2017, each = 4),
Grp = c("Grp1", "Grp2", "Grp3", "Grp4"),
Value = trunc(rnorm(12, 2000000, 100000))) )
ggplot(DF) +
geom_bar(aes(x = year, y = Value, fill = Grp),
stat = "identity",
position = position_stack()) +
geom_text(aes(x = year, y = Value, group = Grp,
label = percent(Value/sum(Value))) ,
position = position_stack(vjust = .5))
使用 position = "fill"
将比例转换为比例,使用 scale_y_continuous(labels = percent_format())
将比例转换为百分比。
DF <- data.frame( year = rep(2015:2017, each = 4),
Grp = c("Grp1", "Grp2", "Grp3", "Grp4"),
Value = trunc(rnorm(12, 2000000, 100000)))
library(ggplot2)
library(scales)
ggplot(DF, aes(year, Value, fill = Grp)) +
geom_bar(stat = "identity", position = "fill") +
geom_text(aes(label = percent(Value / sum(Value))),
position = position_fill()) +
scale_y_continuous(labels = percent_format())
您可以按年份为百分位数创建一个新变量:
library(dplyr)
library(ggplot2)
library(scales)
DF <- DF %>% group_by(year) %>% mutate(ValuePer=(Value/sum(Value))) %>% ungroup()
ggplot(DF, aes(year, ValuePer, fill = Grp)) +
geom_bar(stat = "identity", position = "fill") +
geom_text(aes(label = percent(ValuePer)),
position = position_fill())+
scale_y_continuous(labels = percent_format())
我会为每个柱使用单个 geom_text
,同时使用 dplyr
按 year
(柱)过滤数据。检查是否是您需要的:
(DF <- data.frame( year = rep(2015:2017, each = 4),
Grp = c("Grp1", "Grp2", "Grp3", "Grp4"),
Value = trunc(rnorm(12, 2000000, 100000))) )
library(dplyr)
ggplot(DF) +
geom_bar(aes(x = year, y = Value, fill = Grp),
stat = "identity",
position = position_stack()) +
geom_text(data = DF %>% filter(year == 2015),
aes(x = year, y = Value,
label = scales::percent(Value/sum(Value))) ,
position = position_stack(vjust = .5)) +
geom_text(data = DF %>% filter(year == 2016),
aes(x = year, y = Value,
label = scales::percent(Value/sum(Value))) ,
position = position_stack(vjust = .5)) +
geom_text(data = DF %>% filter(year == 2017),
aes(x = year, y = Value,
label = scales::percent(Value/sum(Value))) ,
position = position_stack(vjust = .5))
这里不需要参数 group
。可能有更优雅的解决方案,但这是我能想到的解决方案。告诉我这是否是您正在等待的输出:
也许创建一个新列来进行正确的计算。我无法弄清楚如何在 aes()
内部进行计算,就像您刚才计算总体百分比的方式一样,Value
应该按 year
分组。
至少你自己得到了 Y 轴的实际值和 Year 分组的 % inside bars。我建议通过堆叠这样的东西来更改此标签:
scale_y_continuous(breaks = seq(0,8*10^6,10^6),
labels = c(0, paste(seq(1,8,1),'M')))
结果如下:
你可以适应你的环境。
好的,集齐你所有的技巧,我终于明白了:
我需要调整我的 DF,这是我想避免的,但它仍然很简单,所以它有效
library(dplyr)
library(ggplot2)
library(scales)
DF <- DF %>% group_by(year) %>% mutate(ValuePer=(Value/sum(Value))) %>% ungroup()
ggplot(DF, aes(year, Value, fill = Grp)) +
geom_bar(stat = "identity", position = "stack") +
geom_text(aes(label = percent(ValuePer)),
position = position_stack()) +
scale_y_continuous(labels = unit_format("M", 1e-6) )
我正在尝试为每个组绘制一个基本条形图。
由于值非常大,我想显示 对于每个柱状图 (即组),柱状图 中每个组的 % .
我设法显示了总数的百分比,但这不是我所期望的:在每个栏中,我希望 % 的总和等于 100%。
有没有不改变数据帧的简单方法?
(DF <- data.frame( year = rep(2015:2017, each = 4),
Grp = c("Grp1", "Grp2", "Grp3", "Grp4"),
Value = trunc(rnorm(12, 2000000, 100000))) )
ggplot(DF) +
geom_bar(aes(x = year, y = Value, fill = Grp),
stat = "identity",
position = position_stack()) +
geom_text(aes(x = year, y = Value, group = Grp,
label = percent(Value/sum(Value))) ,
position = position_stack(vjust = .5))
使用 position = "fill"
将比例转换为比例,使用 scale_y_continuous(labels = percent_format())
将比例转换为百分比。
DF <- data.frame( year = rep(2015:2017, each = 4),
Grp = c("Grp1", "Grp2", "Grp3", "Grp4"),
Value = trunc(rnorm(12, 2000000, 100000)))
library(ggplot2)
library(scales)
ggplot(DF, aes(year, Value, fill = Grp)) +
geom_bar(stat = "identity", position = "fill") +
geom_text(aes(label = percent(Value / sum(Value))),
position = position_fill()) +
scale_y_continuous(labels = percent_format())
您可以按年份为百分位数创建一个新变量:
library(dplyr)
library(ggplot2)
library(scales)
DF <- DF %>% group_by(year) %>% mutate(ValuePer=(Value/sum(Value))) %>% ungroup()
ggplot(DF, aes(year, ValuePer, fill = Grp)) +
geom_bar(stat = "identity", position = "fill") +
geom_text(aes(label = percent(ValuePer)),
position = position_fill())+
scale_y_continuous(labels = percent_format())
我会为每个柱使用单个 geom_text
,同时使用 dplyr
按 year
(柱)过滤数据。检查是否是您需要的:
(DF <- data.frame( year = rep(2015:2017, each = 4),
Grp = c("Grp1", "Grp2", "Grp3", "Grp4"),
Value = trunc(rnorm(12, 2000000, 100000))) )
library(dplyr)
ggplot(DF) +
geom_bar(aes(x = year, y = Value, fill = Grp),
stat = "identity",
position = position_stack()) +
geom_text(data = DF %>% filter(year == 2015),
aes(x = year, y = Value,
label = scales::percent(Value/sum(Value))) ,
position = position_stack(vjust = .5)) +
geom_text(data = DF %>% filter(year == 2016),
aes(x = year, y = Value,
label = scales::percent(Value/sum(Value))) ,
position = position_stack(vjust = .5)) +
geom_text(data = DF %>% filter(year == 2017),
aes(x = year, y = Value,
label = scales::percent(Value/sum(Value))) ,
position = position_stack(vjust = .5))
这里不需要参数 group
。可能有更优雅的解决方案,但这是我能想到的解决方案。告诉我这是否是您正在等待的输出:
也许创建一个新列来进行正确的计算。我无法弄清楚如何在 aes()
内部进行计算,就像您刚才计算总体百分比的方式一样,Value
应该按 year
分组。
至少你自己得到了 Y 轴的实际值和 Year 分组的 % inside bars。我建议通过堆叠这样的东西来更改此标签:
scale_y_continuous(breaks = seq(0,8*10^6,10^6),
labels = c(0, paste(seq(1,8,1),'M')))
结果如下:
你可以适应你的环境。
好的,集齐你所有的技巧,我终于明白了: 我需要调整我的 DF,这是我想避免的,但它仍然很简单,所以它有效
library(dplyr)
library(ggplot2)
library(scales)
DF <- DF %>% group_by(year) %>% mutate(ValuePer=(Value/sum(Value))) %>% ungroup()
ggplot(DF, aes(year, Value, fill = Grp)) +
geom_bar(stat = "identity", position = "stack") +
geom_text(aes(label = percent(ValuePer)),
position = position_stack()) +
scale_y_continuous(labels = unit_format("M", 1e-6) )