Adding counts to ggmosaic, can this be done simpler?

I've previously made similar charts in pure ggplot2, without using the ggmosaic package. I don't know if this would be sufficient for your use case, though:

# data manipulation
data %>%
  group_by(a, b) %>%
  summarise(n = n()) %>%
  mutate(x.width = sum(n)) %>%

  # simulate mosaic plot
  ggplot(aes(x = factor(a), y = n)) +
  geom_col(aes(width = x.width, fill = factor(b)),
           colour = "white", size = 1, position = position_fill(reverse = TRUE)) +
  geom_label(aes(label = n),
             position = position_fill(vjust = 0.5)) +
  facet_grid(~ a, space = "free", scales = "free", switch = "x") +

  # cosmetic tweaks
  scale_x_discrete(name = "a") +
  scale_y_continuous(labels = scales::percent) +
  theme(axis.text.x = element_blank(),
        axis.ticks.x = element_blank(),
        axis.title.y = element_blank(),
        strip.background = element_blank(),
        panel.spacing = unit(0, "pt"))

plot


Here's a way to do this using the supplied code, but without needing to save a temporary plot. It makes use of ggplot's last_plot to access the plot object up to the most recent '+', and also accesses the data a bit more simply using layer_data, rather than ggplot_build.

library(tidyverse)
library(ggmosaic)
data <- tribble(~a, ~b, 
                1, 1, 
                1, 1, 
                1, 1, 
                1, 2, 
                2, 1,
                2, 2, 
                3, 2)

data <- data %>%
  mutate(across(c(a, b), as.factor))

ggplot(data) + 
  geom_mosaic(aes(x=product(b, a), fill=b)) +
  geom_label(data = layer_data(last_plot(), 1) %>% filter(.wt > 0),
             aes(x = (xmin + xmax) / 2,
                 y = (ymin + ymax) / 2,
                 label = .wt))

Created on 2020-07-05 by the reprex package (v0.3.0)

It's still a hack, but it will save you the pain of assigning a temporary plot.