Adding in text (from a column) to stacked bar chart ggplot in R

65 Views Asked by At

Here is my sample dataset and I would like to make a stacked barchart.

dat <- data.frame(practice =c("walk in", "ltc", "emerg", "specialty"),
                   in_person=c(2463,987,3029,1200),
                  virtual = c(233,278,109,409),
                   percent_of_virtual =  c(8.6, 22, 3.5,25.4))

dat1 <-dat[c(1,2,3)]

dat1 <- dat1 %>%
  tidyr::pivot_longer(cols=-c(practice), names_to = "visit", values_to = "Number")

ggplot(dat1, aes(x = practice, y = Number, fill = visit)) +
  geom_col(position=position_stack(reverse = TRUE)) + coord_flip()

Using the above code I get the following stacked chart. This is what I want but I would like to add in the variable "percent_of_virtual" from "dat" as text at the outside of each bar.

enter image description here

I need the output to look something like the below. As you see here for each practice the % of virtual visits (calculated as virtual visit/virtual visit+in_person visit) is added as text. I tried doing this with geom_text but was unsuccessful. I would like to find a method without manually having to add the text in because I have to do this for multiple graphs. Any help would be appreciated!!

enter image description here

1

There are 1 best solutions below

2
On BEST ANSWER

You need to use position_stack on the text. I would probably change your data shaping to include the percentage column, but conditionally mask it for the in person group:

dat %>%
  tidyr::pivot_longer(2:3, names_to = "visit", values_to = "Number") %>%
  ggplot(aes(x = practice, y = Number, fill = visit)) +
  geom_col(position = position_stack(reverse = TRUE), width = 0.5) + 
  geom_text(aes(label = ifelse(visit == "virtual", 
                               paste0(percent_of_virtual, "%"), "")),
            position = position_stack(vjust = 1, reverse = TRUE),
            hjust = -0.5, size = 6) +
  ylim(c(0, 4000)) +
  scale_fill_manual(values = c("gray50", "orange")) +
  coord_flip() +
  theme_minimal(base_size = 20)

enter image description here