如何使用 ggplot2 facet_grid 注释没有数据的方面?

How can I annotate facets that do not have data using ggplot2 facet_grid?

我有一个多变量纵向样本,我在一个大的 facet_grid 中绘制,特别是使用 facet_grid 这样当我没有某个样本的某个时间点时它仍然保留所有内容在一个井井有条的网格中。我正在尝试向空面添加某种指示器以表明它们没有数据(而不是只是没有显示任何点),因为有时空面是尚未收集该样本的结果。我能够得到的是一个标签,该标签显示在每个没有数据的方面,但我似乎无法弄清楚如何获得一个标签显示在每个没有数据的方面。如果我可以通过 select 方面添加一个红色的 X,或者 "No Data Available" 的一些其他指示,而不是文本标签,如果你对此也有建议的话,那就更好了。

ggplot(mpg, aes(displ, cty)) + geom_point() + 
facet_grid(vars(drv), vars(cyl)) + geom_text(x = 5, y = 20, label = "Blah")

您可以使用 full_join 为缺失的组合添加行。这些新行将没有数据,因此不会绘制任何内容,但您可以添加一个附加列,其中包含 geom_text 将使用的消息:

library(tidyverse)
theme_set(theme_bw())

mpg %>% 
  full_join(crossing(drv=unique(mpg$drv), cyl=unique(mpg$cyl))) %>% 
  mutate(empty=ifelse(is.na(model), "No data available", NA_character_),
         x=mean(range(displ, na.rm=TRUE)), 
         y=mean(range(cty, na.rm=TRUE))) %>% 
  ggplot(aes(displ, cty)) + 
    geom_point() + 
    facet_grid(vars(drv), vars(cyl)) + 
    geom_text(aes(x, y, label=empty), colour="red", size=3)

对于 "X",将 empty 文本更改为 "X" 并以较大尺寸绘制。例如:

mpg %>% 
  full_join(crossing(drv=unique(mpg$drv), cyl=unique(mpg$cyl))) %>% 
  mutate(empty=ifelse(is.na(model), "X", NA_character_),
         x=mean(range(displ, na.rm=TRUE)), 
         y=mean(range(cty, na.rm=TRUE))) %>% 
  ggplot(aes(displ, cty)) + 
    geom_point() + 
    geom_text(aes(x, y, label=empty), colour="red", size=20) +
    facet_grid(vars(drv), vars(cyl))

或者我们可以使用 geom_segment:

mpg %>% 
  full_join(crossing(drv=unique(mpg$drv), cyl=unique(mpg$cyl))) %>% 
  ggplot(aes(displ, cty)) + 
    geom_point() + 
    geom_segment(data=. %>% filter(is.na(model)),
                 x=min(mpg$displ), xend=max(mpg$displ),
                 y=min(mpg$cty), yend=max(mpg$cty),
                 colour="red") +
    geom_segment(data=. %>% filter(is.na(model)),
                 x=min(mpg$displ), xend=max(mpg$displ),
                 y=max(mpg$cty), yend=min(mpg$cty),
                 colour="red") +
    facet_grid(vars(drv), vars(cyl))

以上可以通过一次调用 geom_segment 来完成,但它需要 (AFAICT) 更复杂的数据准备:

mpg %>% 
  full_join(crossing(drv=unique(mpg$drv), cyl=unique(mpg$cyl))) %>% 
  ggplot(aes(displ, cty)) + 
    geom_point() + 
    geom_segment(data=. %>% 
                   filter(is.na(model)) %>% 
                   select(-displ, -cty) %>% 
                   crossing(
                     displ=range(mpg$displ),
                     cty=range(mpg$cty)
                   ),
                 aes(xend=rev(displ), yend=rev(cty)), colour="red") +
    facet_grid(vars(drv), vars(cyl))