如何将每个类别的百分比添加到堆积条形图(ggplot2)(对于“非百分比”堆积图表)
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何将每个类别的百分比添加到堆积条形图(ggplot2)(对于“非百分比”堆积图表)相关的知识,希望对你有一定的参考价值。
如何将每个类别的百分比添加到轴的堆积条形图而不是填充。例如,我有以下数据集:
df<-structure(list(age_group = structure(c(3L, 3L, 5L, 3L, 5L, 5L,
5L, 3L, 5L, 5L, 4L, 4L, 4L, 3L, 5L), .Label = c("65+", "55-64",
"45-54", "35-44", "25-34", "18-24"), class = "factor"), Gender = c("F",
"M", "M", "M", "F", "M", "M", "M", "F", "M", "M", "F", "M", "F",
"M")), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA,
-15L), .Names = c("age_group", "Gender"))
dat <- aggregate(list(value = 1:NROW(df)), df[c("age_group", "Gender")], length)
dat$proportion <- ave(dat$value, dat$age_group, FUN = function(x) (x/sum(x)*100))
dat$proportionR <- round(dat$proportion, digits =0)
dat<-dat %>%
group_by(age_group) %>%
mutate(age_per = sum(value)) %>%
ungroup() %>%
mutate(age_per = round((age_per/sum(value))*100))
ggplot(dat, aes(x = age_group, y = value, fill = Gender)) +
geom_col() + coord_flip() + ylab("Visits 2018-2019") +xlab("") +
scale_fill_manual(values= c("#740404", "#AB6868", "#D5B3B3"), labels = c("Females", "Males", "N/A")) +
theme(legend.title=element_blank()) +
geom_text(aes(label = paste0(age_per, "%")), hjust = 2.7, position = "stack", color = "white", size =5)
我想要的是一种自动方式,从y轴添加每个组的总百分比,同时忽略每个组中的百分比。我的工作流程识别正确的百分比,但在堆栈中的每个子组上复制它。我希望geom_text
在酒吧结束后立即放置在白色空间。
就像一个注释,问题不是以下SO Q -Adding percentage labels to a bar chart in ggplot2的重复 - 因为这个问题涉及每个条形图中有堆叠组的百分比(前者仅用于条形图)。
另外,强调自动化。我可以执行以下操作,但在我的实际数据集中,我有更多的年龄组间隔,这使得下面的方法难以理解。
ggplot(dat, aes(x = age_group, y = value, fill = Gender)) +
geom_col() + coord_flip() + ylab("Visits 2018-2019") +xlab("") +
scale_fill_manual(values= c("#740404", "#AB6868", "#D5B3B3"), labels = c("Females", "Males", "N/A")) +
theme(legend.title=element_blank()) +
geom_text(aes(y= 5.2, x=1, label = "33%"), color = "#740404", size =5) +
geom_text(aes(y= 3.2, x=2, label = "20%"), color = "#740404", size =5) +
geom_text(aes(y= 7.2, x=3, label = "47%"), color = "#740404", size =5)
答案
考虑使用分组百分比计算进行注释。由于你需要添加三个系列的六个数字,annotate
可以与分组系列不同。此外,使用适当的性别和年龄组百分比。在另一个base::ave
电话下面替换你的dplyr::group_by
:
agg_df <- aggregate(list(value = 1:NROW(df)), df[c("age_group", "Gender")], length)
dat <- within(agg_df, {
proportion <- ave(value, age_group, FUN = function(x) (x/sum(x)*100))
proportionR <- round(proportion, digits=0)
age_per <- round((ave(value, age_group, Gender, FUN=sum) / sum(value)) * 100)
grp_pct <- round((ave(value, age_group, FUN=sum) / sum(value)) * 100)
})
dat
# age_group Gender value grp_pct age_per proportionR proportion
# 1 45-54 F 2 33 13 40 40.00000
# 2 35-44 F 1 20 7 33 33.33333
# 3 25-34 F 2 47 13 29 28.57143
# 4 45-54 M 3 33 20 60 60.00000
# 5 35-44 M 2 20 13 67 66.66667
# 6 25-34 M 5 47 33 71 71.42857
ggplot(dat, aes(x = age_group, y = value, fill = Gender)) +
geom_col() + coord_flip() + ylab("Visits 2018-2019") +xlab("") +
scale_fill_manual(values= c("#740404", "#AB6868", "#D5B3B3"),
labels = c("Females", "Males", "N/A")) +
theme(legend.title=element_blank()) +
geom_text(aes(label = paste0(age_per, "%")), hjust = 2.7,
position = "stack", color = "white", size =5) +
annotate("text", x=1, y=5.25, label = paste0(dat$grp_pct[[1]], "%")) +
annotate("text", x=2, y=3.25, label = paste0(dat$grp_pct[[2]], "%")) +
annotate("text", x=3, y=7.25, label = paste0(dat$grp_pct[[3]], "%"))
对于动态注释,您可能必须使用ggplot
的函数形式Reduce
,其中+
(实际上不是加算术运算符)作为+.gg()
运算符公开。然后,调用mapply
迭代unique(grp_pct)
以传入x坐标位置并注释标签。剩下的挑战是最好的y坐标是未知的。
Reduce(ggplot2:::`+.gg`,
c(list(ggplot(dat, aes(x = age_group, y = value, fill = Gender)),
geom_col(), coord_flip(), ylab("Visits 2018-2019"), xlab(""),
scale_fill_manual(values= c("#740404", "#AB6868", "#D5B3B3"),
labels = c("Females", "Males", "N/A")),
theme(legend.title=element_blank()),
geom_text(aes(label = paste0(age_per, "%")), hjust = 2.7,
position = "stack", color = "white", size =5)
),
Map(function(x_loc, g_lab) annotate("text", x=x_loc, y=7.25,
label = paste0(g_lab, "%")),
seq(length(unique(dat$grp_pct))), unique(dat$grp_pct)
)
)
)
以上是关于如何将每个类别的百分比添加到堆积条形图(ggplot2)(对于“非百分比”堆积图表)的主要内容,如果未能解决你的问题,请参考以下文章