использование переменной группировки и geom_rect

#r #ggplot2

Вопрос:

Я хочу показать охватываемые диапазоны (включая перекрытия) и (после некоторых сбоев с построенными столбчатыми диаграммами) Я выбрал geom_rect. Следующий код хорошо работает для одного типа.

 library(tidyverse)

# create dummy data
foo <- tibble(start = c(1, 150, 140, 75, 300),
              end = c(150, 180, 170, 160, 400))

ggplot()  
  geom_rect(data = foo, aes(xmin = start, xmax = end, ymin = 0, ymax = 1), fill = "green", linetype = "blank", alpha = 0.3)  
  geom_rect(data = foo, aes(xmin = 1, xmax = max(end), ymin = 0, ymax = 1), fill = NA, colour = "black")  
  scale_y_continuous(name = "", breaks = NULL, limits = c(0, 1))  
  scale_x_continuous(name = "", breaks = NULL)  
  theme_minimal()  
  theme(panel.grid = element_blank())
 

ggplot geom_rect 1-я попытка

Если я добавлю больше данных (только еще один тип, но в исходных данных у меня есть еще несколько), как показано ниже, я могу добавить данные «вручную», т. Е. Добавить две строки кода для каждого типа, но я ищу способ сделать это путем группировки, но не преуспел.

 foo <- foo %>%
  mutate(type = "A", .before = 1)
bar <- tibble(type = "B",
              start = c(1, 30, 40, 100, 150, 200, 310),
              end = c(20, 50, 100, 120, 200, 300, 380))
foo <- bind_rows(foo, bar)

ggplot()  
  geom_rect(data = foo %>% filter(type == "A"), aes(xmin = start, xmax = end, ymin = 0, ymax = 1), fill = "green", linetype = "blank", alpha = 0.3)  
  geom_rect(data = foo, aes(xmin = 1, xmax = max(end), ymin = 0, ymax = 1), fill = NA, colour = "black")  
  geom_rect(data = foo %>% filter(type == "B"), aes(xmin = start, xmax = end, ymin = 2, ymax = 3), fill = "green", linetype = "blank", alpha = 0.3)  
  geom_rect(data = foo, aes(xmin = 1, xmax = max(end), ymin = 2, ymax = 3), fill = NA, colour = "black")  
  scale_y_continuous(name = "", breaks = NULL, limits = c(0, 3))  
  scale_x_continuous(name = "", breaks = NULL)  
  geom_text(aes(x = c(0, 0), y = c(0.5, 2.5), label = c("A", "B")), size = 4, hjust = 2)  
  theme_minimal()  
  theme(panel.grid = element_blank())
 

ggplot geom_rect 2-я попытка

Итак, график уже выглядит так, как я хочу, но я предпочел бы попасть сюда с помощью группировки (или любым другим способом, не связанным с руководством).

Может быть, есть также другая геометрия или метод получения такого графика?

Ответ №1:

Вы можете написать небольшую вспомогательную функцию, которая размещает категориальное значение в непрерывном пространстве. Пример ниже.

 helper <- function(x) {(match(x, sort(unique(x))) - 1) * 2}

ggplot(foo)  
  geom_rect(
    aes(xmin = start, xmax = end, 
        ymin = helper(type), 
        ymax = helper(type)   1), 
    fill = "green", linetype = "blank", alpha = 0.3
  )  
  geom_rect(
    aes(xmin = min(start), xmax = max(end),
        ymin = helper(type),
        ymax = helper(type)   1),
    fill = NA, colour = "black"
  )  
  scale_y_continuous(name = "", breaks = NULL, limits = c(0, 3))  
  scale_x_continuous(name = "", breaks = NULL)  
  annotate(
    "text", x = c(0, 0), y = c(0.5, 2.5), label = c("A", "B"), 
    size = 4, hjust = 2
  )  
  theme_minimal()  
  theme(panel.grid = element_blank())