How to use stat="count" to label a bar chart with counts or percentages in ggplot2?

Viewed 6965

I'm trying to produce a stacked column chart with data labels.

I'm able to produce the chart, but was unable to find a way to input data labels. I have tried geom_text() but it keeps asking me to input a y label (which if you see the ggplot code is not there). I have also tried adding geom_text(stat = "count") but that also gives me an error saying

"Error: geom_text requires the following missing aesthetics: y and label".

PS - i'm aware I need to rename the y axis as percentage. I'm also trying to figure out how to have more contrasting colours

ggplot(property,
       aes(x=Bedrooms.New, fill=Property.Type.)) + 
  geom_bar(position = "fill") + 
  scale_x_discrete(name = "Number of Bedrooms", 
                   limits = sort(factor(unique(property$Bedrooms.New))))

I have added an image below to see what my output is right now!

enter image description here

1 Answers

As the error message is telling you, geom_text requires the label aes. In your case you want to label the bars with a variable which is not part of your dataset but instead computed by stat="count", i.e. stat_count.

The computed variable can be accessed via ..NAME_OF_COMPUTED_VARIABLE... , e.g. to get the counts use ..count.. as variable name. BTW: A list of the computed variables can be found on the help package of the stat or geom, e.g. ?stat_count

Using mtcars as an example dataset you can label a geom_bar like so:

library(ggplot2)

ggplot(mtcars, aes(cyl, fill = factor(gear)))+
  geom_bar(position = "fill") +
  geom_text(aes(label = ..count..), stat = "count", position = "fill")

Two more notes:

  1. To get the position of the labels right you have to set the position argument to match the one used in geom_bar, e.g. position="fill" in your case.

  2. While counts are pretty easy, labelling with percentages is a different issue. By default stat_count computes percentages by group, e.g. by the groups set via the fill aes. These can be accessed via ..prop... If you want the percentages to be computed differently, you have to do it manually.

As an example if you want the percentages to sum to 100% per bar this could be achieved like so:

library(ggplot2)

ggplot(mtcars, aes(cyl, fill = factor(gear)))+
  geom_bar(position = "fill") +
  geom_text(aes(label = ..count.. / tapply(..count.., ..x.., sum)[as.character(..x..)]), stat = "count", position = "fill")

Related