Add percentage labels to a bar chart
bar-chart, ggplot2, r
Solution
It's easiest to calculate the quantities you need beforehand, outside of ggplot, as it's hard to track what ggplot calculates and where those quantities are stored and available.
First, summarize your data:
library(dplyr)
library(ggplot2)
mtcars %>%
count(cyl = factor(cyl), gear = factor(gear)) %>%
mutate(pct = prop.table(n))
#> # A tibble: 8 x 4
#> cyl gear n pct
#> <fct> <fct> <int> <dbl>
#> 1 4 3 1 0.0312
#> 2 4 4 8 0.25
#> 3 4 5 2 0.0625
#> 4 6 3 2 0.0625
#> 5 6 4 4 0.125
#> 6 6 5 1 0.0312
#> 7 8 3 12 0.375
#> 8 8 5 2 0.0625
Save that if you like, or pipe directly into ggplot:
mtcars %>%
count(cyl = factor(cyl), gear = factor(gear)) %>%
mutate(pct = prop.table(n)) %>%
ggplot(aes(x = cyl, y = pct, fill = gear, label = scales::percent(pct))) +
geom_col(position = 'dodge') +
geom_text(position = position_dodge(width = .9), # move to center of bars
vjust = -0.5, # nudge above top of bar
size = 3) +
scale_y_continuous(labels = scales::percent)
If you really want to keep it all internal to ggplot, you can use `geom_text` with `stat = 'count'` (or `stat_count` with `geom = "text"`, if you prefer):
ggplot(data = mtcars, aes(x = factor(cyl),
y = prop.table(stat(count)),
fill = factor(gear),
label = scales::percent(prop.table(stat(count))))) +
geom_bar(position = "dodge") +
geom_text(stat = 'count',
position = position_dodge(.9),
vjust = -0.5,
size = 3) +
scale_y_continuous(labels = scales::percent) +
labs(x = 'cyl', y = 'pct', fill = 'gear')
which plots exactly the same thing.
Problem
How can I use `geom_text` to add percentage labels on top of each bar in `ggplot2`? I know there are several similar questions which are already answered. But they either use only 1 categorical variable or compute the percentages before plotting. I have following plot: ``` ggplot(data = mtcars)+ geom_bar(aes(x = factor(cyl), y = (..count..)/sum(..count..)*100, fill = factor(gear)), position = "dodge") ``` Now I want to add the percentage labels on the top. If I use `y = (..count..)/sum(..count..)*100` in `geom_text`, it says `Error in eval(expr, envir, enclos) : object 'count' not found`.