0

I have a dataset which looks like this:

Smoking population
1      yes     group1
2      yes     group3
3      yes     group2
4       no     group1
5       no     group1
6      yes     group3
7       no     group2
8      yes     group2
9      yes     group3
10      no     group1
11      no     group1
12      no     group3
13     yes     group2
14      no     group2
15      no     group1
16     yes     group1
17     yes     group2
18      no     group3
19      no     group3
20     yes     group1
21      no     group3

I am trying to plot population on the x axis and count on the y axis for yes and no like this:

library(tidyverse)
    df %>%
      ggplot(aes(x = population , color = Smoking, fill = Smoking)) +
      geom_bar(position = 'dodge')+ 
      theme(axis.text.x = element_text(angle=90, vjust=.5, hjust=1))

enter image description here

I need to add the count at the top of the bars. How can I do that?

user3138373
  • 519
  • 1
  • 6
  • 18
  • Does this address your question? https://stackoverflow.com/questions/12018499/how-to-put-labels-over-geom-bar-for-each-bar-in-r-with-ggplot2 – Jon Spring Mar 22 '23 at 20:21
  • The problem is, I don't have the counts already calculated and in separate column – user3138373 Mar 22 '23 at 20:24

2 Answers2

1

This changed in ggplot 3.4.0 (November 2022). If you search for questions on this you'll see a lot of code that uses either stat() or ..count...

However, this was deprecated in 3.4.0. You can now use after_stat(count) to calculate the counts:

ggplot(df, aes(x = population, color = Smoking, fill = Smoking)) +
    geom_bar(position = "dodge") +
    theme(axis.text.x = element_text(angle = 90, vjust = .5, hjust = 1)) +
    geom_text(
        stat = "count",
        aes(
            label = after_stat(count)
        ),
        position = position_dodge(),
        color = "black",
        size = 8,
        vjust = -0.2
    )

enter image description here

Axeman
  • 32,068
  • 8
  • 81
  • 94
SamR
  • 8,826
  • 3
  • 11
  • 33
  • 1
    What is this doing `position_dodge(width=0.9)`. Fixing the alignment of the numbers? – user3138373 Mar 22 '23 at 20:32
  • Good point. The `position_dodge()` makes sure that the labels are "dodged", i.e. grouped, like the bars are. Otherwise both labels would be at the point the two bars meet. However, the 0.9 is not necessary - I copied and pasted this from some code I wrote yesterday where the width of the bars was 0.9. In your case you can take that bit out - I'll edit the answer. – SamR Mar 22 '23 at 20:35
0

I like getting the counts within geom_text as in @SamR answer.

Another way is to calculate the counts prior to calling ggplot and then use them in geom_text

df %>% 
  mutate(count_data = n(), .by = c(population, Smoking)) %>% 
  ggplot(aes(x = population , color = Smoking, fill = Smoking)) + 
  geom_bar(position = 'dodge') + 
  geom_text(aes(population, count_data, label = count_data), 
    vjust=-.5, color="black", position = position_dodge(.9)) + 
  theme(axis.text.x = element_text(angle=90, vjust=.5, hjust=1))

barplot

Andre Wildberg
  • 12,344
  • 3
  • 12
  • 29