我想在一张图表上绘制多个类别,每个类别的百分比加起来为 100%。例如,如果我绘制男性与女性的图,则每个分组(男性或女性)加起来将为 100%。我正在使用以下代码,其中百分比似乎适用于两个图表上的所有组,即,如果将左侧和右侧图表上的所有条形图相加,它们的总和将是 100%,而不是右侧图表上的黄色条形图左手图总计 100%,左手图上的紫色条总计 100% 等等
我很欣赏这可以通过使用 stat = 'identity' 来实现,但是有没有办法在 ggplot 中做到这一点,而无需在绘图之前处理数据帧?
library(ggplot2)
tmp <- diamonds %>% filter(color %in% c("E","I")) %>% select(color, cut, clarity)
ggplot(data=tmp,
aes(x=clarity,
fill=cut)) +
geom_bar(aes(y = (..count..)/sum(..count..)), position="dodge") +
scale_y_continuous(labels = scales::percent) + facet_wrap(vars(color))
在 ggplot2 中计算百分比时,您必须像在将数据传递给 ggplot 之前汇总数据时一样对数据进行分组。在您的情况下,由 ggplot2 在数据内部添加的
PANEL
列可用于分组:
使用
after_stat
和 tapply
可以这样实现:
library(ggplot2)
library(dplyr)
tmp <- diamonds %>% filter(color %in% c("E","I")) %>% select(color, cut, clarity)
ggplot(data=tmp,
aes(x=clarity,
fill=cut)) +
geom_bar(aes(y = after_stat(count/tapply(count, PANEL, sum)[PANEL])), position="dodge") +
scale_y_continuous(labels = scales::percent) + facet_wrap(vars(color))
或使用
..
表示法:
ggplot(data=tmp,
aes(x=clarity,
fill=cut)) +
geom_bar(aes(y = ..count../tapply(..count.., ..PANEL.., sum)[..PANEL..]), position="dodge") +
scale_y_continuous(labels = scales::percent) + facet_wrap(vars(color))
编辑如果您需要按多个变量进行分组,我建议使用辅助函数,其中我使用
dplyr
进行计算:
comp_pct <- function(count, PANEL, cut) {
data.frame(count, PANEL, cut) %>%
group_by(PANEL, cut) %>%
mutate(pct = count / sum(count)) %>%
pull(pct)
}
ggplot(data=tmp,
aes(x=clarity,
fill=cut)) +
geom_bar(aes(y = after_stat(comp_pct(count, PANEL, fill))), position="dodge") +
scale_y_continuous(labels = scales::percent) + facet_wrap(vars(color))