1

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:

  • LICENCE_STATUS: Active
  • Marking Variables: THIRD_PARTY_MARKETING_ALLOWED

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))+

John Thomas
  • 1,075
  • 9
  • 32
  • Are the example data the same as you used for the plot? The values "IN_DISPUTE", "REVOKED" and "TRIAL_EXPIRED" don't appear in the example data? – colebrookson Jan 20 '22 at 19:43
  • 1
    Does this answer your question? [Showing data values on stacked bar chart in ggplot2](https://stackoverflow.com/questions/6644997/showing-data-values-on-stacked-bar-chart-in-ggplot2) – divibisan Jan 20 '22 at 20:19
  • @colebrookson the dput data is the actual data, the plot i show only shows three. – John Thomas Jan 20 '22 at 23:23
  • @divibisan, I am looking for the geom_label() solution specifically – John Thomas Jan 20 '22 at 23:24
  • 1
    @JohnThomas `geom_text` and `geom_label` are pretty much identical. The only difference is that label draws a rectangle behind the text. So the answers on the duplicate that use `geom_text` should work just as well with `geom_label`. Give them a try. If they don't work, edit your question to show what you did and why those answers are not satisfactory. That will help us narrow down the specifics of your problem – divibisan Jan 20 '22 at 23:41
  • @divibisan added why this will not work – John Thomas Jan 21 '22 at 02:12

1 Answers1

2

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)

stefan
  • 90,330
  • 6
  • 25
  • 51
  • this is good! what do u recommend about the cutoff on the right most plots? – John Thomas Jan 24 '22 at 21:44
  • 1
    Cut your the labels mapped on y to make more room for the plot. :D It that is not an option use `+ coord_cartesian(clip = "off")` to prevent the labels from be clipped off, reduce the font size and perhaps increase the spacing between the panels using `theme(panel.spacing.x = unit(...., "pt"))` – stefan Jan 24 '22 at 21:51