将计数添加到 ggmosaic,这可以做得更简单吗?

Adding counts to ggmosaic, can this be done simpler?

我想使用 ggmosaic 包制作马赛克图并添加计数,如下例所示。

该示例可以工作,但我发现代码的结构非常难看。 您对我如何改进代码以使其更具可重用性有什么建议吗?

特别是与通常使用 ggplot2 可以实现的相比,将绘图的早期版本存储在临时变量中的需要似乎是错误的。

library(tidyverse)
library(ggmosaic)
#> Indlæser krævet pakke: productplots
#> 
#> Vedhæfter pakke: 'ggmosaic'
#> De følgende objekter er maskerede fra 'package:productplots':
#> 
#>     ddecker, hspine, mosaic, prodcalc, spine, vspine

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

p <- ggplot(data) + 
  geom_mosaic(aes(x=product(b, a), fill=as.factor(b)))

p + 
  geom_label(data = ggplot_build(p)$data %>% as.data.frame() %>% filter(.wt > 0), 
             aes(x = (xmin + xmax)/2, 
                 y = (ymin + ymax)/2, 
                 label = .wt))

reprex package (v0.2.0) 创建于 2018-05-08。

我已经 previously 在没有使用 ggmosaic 包的情况下使用纯 ggplot2 制作了类似的图表。不过,我不知道这是否足以满足您的用例:

# 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"))

这是一种使用提供的代码执行此操作的方法,但无需保存临时绘图。它利用 ggplot 的 last_plot 访问绘图对象直到最近的 '+',并且还使用 layer_data 而不是 ggplot_build.[= 更简单地访问数据。 16=]

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

reprex package (v0.3.0)

于 2020-07-05 创建

它仍然是一个 hack,但它会让你免去分配临时地块的痛苦。

这可以使用 ggmosaic 包的内置标签功能通过一行代码完成。

为此,我们只需添加 geom_mosaic_text() 层:

data <- tribble(~a, ~b, 
                1, 1, 
                1, 1, 
                1, 1, 
                1, 2, 
                2, 1,
                2, 2, 
                3, 2) %>%
  mutate(across(c(a, b), as.factor))

ggplot(data) + 
  geom_mosaic(aes(x=product(b, a), fill=b)) +
  geom_mosaic_text(aes(x = product(b, a), label = after_stat(.wt)), as.label=TRUE)