0

I am trying to use geom_text to label a faceted geom_col plot where the position="fill".

This is a simplified version of the data I am using:

group = c("Group1", "Group1", "Group1", "Group1", "Group1", "Group1","Group2", "Group2", "Group2", "Group2", "Group2", "Group2")

year = c("Year1", "Year2", "Year3", "Year1", "Year2", "Year3", "Year1", "Year2", "Year3", "Year1", "Year2", "Year3")

gender = c("Male", "Male", "Male", "Female", "Female", "Female", "Male", "Male", "Male", "Female", "Female", "Female")

count = c(15, 16, 20, 12, 13, 13, 21, 24, 25, 27, 23, 30)

data = as.data.frame(cbind(group, year, gender, as.integer(count)))

Now, doing this when using geom_line is very straight forward:

data %>%
  ggplot(aes(year, count, color=gender, group=gender))+
  geom_point(size=2.5)+
  geom_line(size=1.5)+
  facet_wrap(~group)+
  geom_label(label=count)

However, when using geom_col and position="fill", thereby creating a proportional plot, this doesn't work, as the labels (as instructed) are the 'count' values.

data %>%
  ggplot(aes(year, count, fill=gender))+
  geom_col(position="fill")+
  facet_wrap(~group)+
  geom_label(label=count)

My question is, as ggplot has the ability to generate proportions in order to create a geom_col-position="fill" style plot, is there a way for me to 'access' these proportions and then use them to label my plot?

Any help would be greatly appreciated.

Thank you.

  • It's less complicated than needing to extract the positions. Add `position = "fill"` to your `geom_label`--is that what you're looking for? – camille Aug 13 '18 at 14:09
  • Hi, thanks for the response. That's nearly what I was looking for. The labels are in the correct place now, but they're still the 'count' values, rather than proportions. For example, the first bar displays '15' and '16', rather than '0.48' and '0.52'. Do you have any help regarding that? Thanks again – user10022403 Aug 13 '18 at 21:40

1 Answers1

0

You can do just a couple steps of preprocessing to calculate shares for each group, then use that for positioning bars and making labels.

Note also that I'm using just data.frame instead of as.data.frame(cbind()) to keep count as a numeric rather than a factor.

By grouping by year and group, I can calculate proportions for each gender within a combination of those groups.

library(tidyverse)

...

data <- data.frame(group, year, gender, count)

data_props <- data %>%
  group_by(year, group) %>%
  mutate(prop = round(count / sum(count), digits = 2)) 

data_props
#> # A tibble: 12 x 5
#> # Groups:   year, group [6]
#>    group  year  gender count  prop
#>    <fct>  <fct> <fct>  <dbl> <dbl>
#>  1 Group1 Year1 Male      15  0.56
#>  2 Group1 Year2 Male      16  0.55
#>  3 Group1 Year3 Male      20  0.61
#>  4 Group1 Year1 Female    12  0.44
#>  5 Group1 Year2 Female    13  0.45
#>  6 Group1 Year3 Female    13  0.39
#>  7 Group2 Year1 Male      21  0.44
#>  8 Group2 Year2 Male      24  0.51
#>  9 Group2 Year3 Male      25  0.45
#> 10 Group2 Year1 Female    27  0.56
#> 11 Group2 Year2 Female    23  0.49
#> 12 Group2 Year3 Female    30  0.55

ggplot(data_props, aes(x = year, y = prop, fill = gender)) +
  geom_col(position = "stack") +
  geom_label(aes(label = prop), position = position_stack(vjust = 0.5)) +
  facet_wrap(~ group)

Created on 2018-08-16 by the reprex package (v0.2.0).

camille
  • 16,432
  • 18
  • 38
  • 60