我想使用
ggplot2
将每组的百分比标签添加到绘图中
带有总体(所有 x 轴组)百分比标签的示例
# library
library(reshape2)
library(tidyverse)
# make plot
p <- ggplot(tips, aes(x= day, group=sex)) +
geom_bar(aes(y = ..prop.., fill = factor(..group..)), stat="count") +
geom_text(aes( label = scales::percent(..prop..),
y= ..prop.. ), stat= "count", position=position_stack(vjust = 0.5)) +
labs(y = "Percent", fill="sex") +
scale_y_continuous(labels = scales::percent)
p
现在我想每天添加标签(即 x 轴组):例如,1 为 52.6%,2 为 47.4%
Fri
我知道如何计算这些值,但是,我不知道如何在 ggplot
调用中执行此操作。
# make percentage labels per day
tips %>%
group_by(day,sex) %>%
summarise(total=n()) %>%
left_join(tips %>% group_by(day) %>% summarise(freq=n()) %>% ungroup()) %>%
mutate(percentage=(total/freq))
#> Joining, by = "day"
#> # A tibble: 8 x 5
#> # Groups: day [4]
#> day sex total freq percentage
#> <fct> <fct> <int> <int> <dbl>
#> 1 Fri Female 9 19 0.474
#> 2 Fri Male 10 19 0.526
#> 3 Sat Female 28 87 0.322
#> 4 Sat Male 59 87 0.678
#> 5 Sun Female 18 76 0.237
#> 6 Sun Male 58 76 0.763
#> 7 Thur Female 32 62 0.516
#> 8 Thur Male 30 62 0.484
由 reprex 包于 2022 年 4 月 2 日创建(v2.0.1)
更新
用
..
替换 after_stat
(在 ggplot2 3.4.0 中已弃用)的所有使用,并使用 ave()
代替 tapply()
,可以这样实现:
library(ggplot2)
# For the "tips" dataset
library(reshape2)
ggplot(tips, aes(x = day, group = sex)) +
geom_bar(aes(
y = after_stat(prop),
fill = factor(after_stat(group))
), stat = "count") +
geom_text(aes(
label = scales::percent(
after_stat(ave(count, x, FUN = function(x) x / sum(x)))
),
y = after_stat(prop)
), stat = "count", position = position_stack(vjust = 0.5)) +
labs(y = "Percent", fill = "sex") +
scale_y_continuous(labels = scales::percent)
原答案
使用
after_stat
(而不是 ..
)和自定义辅助函数来计算百分比,您可以计算每天的百分比并像这样添加标签。基本上,这涉及计算每个 x 轴组或类别的比例:
library(ggplot2)
library(reshape2)
comp_pct <- function(count, group) {
count / tapply(count, group, sum)[group]
}
ggplot(tips, aes(x = day, group = sex)) +
geom_bar(aes(y = ..prop.., fill = factor(..group..)), stat = "count") +
geom_text(aes(
label = after_stat(scales::percent(comp_pct(count, x))),
y = ..prop..
), stat = "count", position = position_stack(vjust = 0.5)) +
labs(y = "Percent", fill = "sex") +
scale_y_continuous(labels = scales::percent)