John Thomas
John Thomas

Reputation: 1105

How to include geom_label for a column ggplot?

Hi so I have some data which looks like this:

   `Marketing Variables`         LICENCE_STATUS count   pct val   
   <chr>                         <chr>          <lgl> <int> <chr> 
 1 RESIDENT_MARKETING_ALLOWED    ACTIVE         FALSE  7612 46.61%
 2 RESIDENT_MARKETING_ALLOWED    ACTIVE         TRUE   8720 53.39%
 3 RESIDENT_MARKETING_ALLOWED    CANCELLED      FALSE   418 52.05%
 4 RESIDENT_MARKETING_ALLOWED    CANCELLED      TRUE    385 47.95%
 5 RESIDENT_MARKETING_ALLOWED    EXPIRED        FALSE 78352 81.85%
 6 RESIDENT_MARKETING_ALLOWED    EXPIRED        TRUE  17373 18.15%
 7 THIRD_PARTY_MARKETING_ALLOWED ACTIVE         FALSE 10629 65.1% 
 8 THIRD_PARTY_MARKETING_ALLOWED ACTIVE         TRUE   5698 34.9% 
 9 THIRD_PARTY_MARKETING_ALLOWED CANCELLED      FALSE   571 70.93%
10 THIRD_PARTY_MARKETING_ALLOWED CANCELLED      TRUE    234 29.07%
11 THIRD_PARTY_MARKETING_ALLOWED EXPIRED        FALSE 85166 88.92%
12 THIRD_PARTY_MARKETING_ALLOWED EXPIRED        TRUE  10612 11.08%

And the goal is I want to make a faceted column chart with the code below:

ggplot(test) +
  geom_col(aes(x = `Marketing Variables`, y = pct, fill = count), position = "fill") +
  coord_flip() +
  theme_minimal()+
  facet_wrap(~LICENCE_STATUS)

The issue however is I want to add a geom_label() of the variable val to each bar. The val I wish to show is for the TRUE count for that variable.

As an example:

The first Column is:

Here we see at count = TRUE, a val of 34.9%. So I want the 34.9% to be 34.9% deep in the bar, or essentially where the blue meets the red.

location of geom_label

Notice, I do not want the val for FALSE to appear anywhere; and yes, only true and false are the options for count in the real data.

Here's the data:

structure(list(`Marketing Variables` = c("RESIDENT_MARKETING_ALLOWED", 
"RESIDENT_MARKETING_ALLOWED", "RESIDENT_MARKETING_ALLOWED", "RESIDENT_MARKETING_ALLOWED", 
"RESIDENT_MARKETING_ALLOWED", "RESIDENT_MARKETING_ALLOWED", "THIRD_PARTY_MARKETING_ALLOWED", 
"THIRD_PARTY_MARKETING_ALLOWED", "THIRD_PARTY_MARKETING_ALLOWED", 
"THIRD_PARTY_MARKETING_ALLOWED", "THIRD_PARTY_MARKETING_ALLOWED", 
"THIRD_PARTY_MARKETING_ALLOWED"), LICENCE_STATUS = c("ACTIVE", 
"ACTIVE", "CANCELLED", "CANCELLED", "EXPIRED", "EXPIRED", "ACTIVE", 
"ACTIVE", "CANCELLED", "CANCELLED", "EXPIRED", "EXPIRED"), count = c(FALSE, 
TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, 
TRUE), pct = c(7612L, 8720L, 418L, 385L, 78352L, 17373L, 10629L, 
5698L, 571L, 234L, 85166L, 10612L), val = c("46.61%", "53.39%", 
"52.05%", "47.95%", "81.85%", "18.15%", "65.1%", "34.9%", "70.93%", 
"29.07%", "88.92%", "11.08%")), row.names = c(NA, -12L), groups = structure(list(
    `Marketing Variables` = c("RESIDENT_MARKETING_ALLOWED", "RESIDENT_MARKETING_ALLOWED", 
    "RESIDENT_MARKETING_ALLOWED", "THIRD_PARTY_MARKETING_ALLOWED", 
    "THIRD_PARTY_MARKETING_ALLOWED", "THIRD_PARTY_MARKETING_ALLOWED"
    ), LICENCE_STATUS = c("ACTIVE", "CANCELLED", "EXPIRED", "ACTIVE", 
    "CANCELLED", "EXPIRED"), .rows = structure(list(1:2, 3:4, 
        5:6, 7:8, 9:10, 11:12), ptype = integer(0), class = c("vctrs_list_of", 
    "vctrs_vctr", "list"))), row.names = c(NA, -6L), class = c("tbl_df", 
"tbl", "data.frame"), .drop = TRUE), class = c("grouped_df", 
"tbl_df", "tbl", "data.frame"))

I am specifically looking for the solution with `geom_label()'

EDIT The reason I am unable to use the linked solution is I get the following error:

Error in layer(data = data, mapping = mapping, stat = stat, geom = GeomText,  : 
  object 'val' not found

This occurs when I add the following:

geom_text(label = val, y = pct, size = 2.5, position = position_stack(vjust = 0.5))+

Upvotes: 1

Views: 806

Answers (1)

stefan
stefan

Reputation: 124658

You could achieve your desired result like so:

  1. As for the bars set position="fill" in geom_label too.
  2. To only add the val if count=TRUE use an ifelse which assigns an NA to FALSE.
  3. To silence the warning about removed missing use na.rm=TRUE.
library(ggplot2)

ggplot(test, aes(x = pct, y = `Marketing Variables`, fill = count)) +
  geom_col(position = "fill") +
  geom_label(aes(label = ifelse(count, val, NA_character_)), position = "fill", na.rm = TRUE, show.legend = FALSE) +
  theme_minimal() +
  facet_wrap(~LICENCE_STATUS)

Upvotes: 2

Related Questions