umair durrani umair durrani - 1 month ago 20
R Question

Adding percentage labels to a bar chart in ggplot2

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
.

Answer

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)

mtcars %>% count(cyl = factor(cyl), gear = factor(gear)) %>% 
    mutate(pct = prop.table(n) * 100)

## Source: local data frame [8 x 4]
## Groups: cyl [3]
## 
##      cyl   gear     n    pct
##   <fctr> <fctr> <int>  <dbl>
## 1      4      3     1  9.091
## 2      4      4     8 72.727
## 3      4      5     2 18.182
## 4      6      3     2 28.571
## 5      6      4     4 57.143
## 6      6      5     1 14.286
## 7      8      3    12 85.714
## 8      8      5     2 14.286

Save that if you like, or pipe directly into ggplot:

mtcars %>% count(cyl = factor(cyl), gear = factor(gear)) %>% 
    mutate(pct = prop.table(n) * 100) %>% 
    ggplot(aes(x = cyl, y = n, fill = gear)) + 
    geom_bar(stat = 'identity', position = 'dodge') + 
    geom_text(aes(y = n + .2,    # nudge above top of bar
                  label = paste0(round(pct, 2), '%')),    # prettify
              position = position_dodge(width = .9), 
              size = 3)

barplot with dodged labels

Comments