Несколько вертикальных заштрихованных областей - PullRequest
0 голосов
/ 16 февраля 2019

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

Я попытался использовать geom_ribbon (я создал переменную, принимающую значение 30, с является вершиной моей оси у, если данные находятся во время WE - информация, приведенная в другом столбце), но вместо получения прямоугольников я получаю трапеции.

В другом посте кто-то предложил использовать "geom_rect" или "annotate", если кто-то знает координаты x и y, но я не вижу, как его адаптировать в моем случае, когда я хочуповторить цветную область на все выходные (это не точно каждые 7 дней, потому что некоторые данные отсутствуют).

У вас есть идеи?Большое спасибо заранее!

  ggplot(Sleep.data, aes(x = DATEID)) +
  geom_line(aes(y = P.DEEP, group = 1), col = "deepskyblue3") + 
  geom_point(aes(y = P.DEEP, group = 1, col = Sign.deep)) +
  guides(col=FALSE) +
  geom_ribbon(aes(ymin = min, ymax = max.WE), fill = '#6495ED80') +
  facet_grid(MONTH~.) +
  geom_hline(yintercept = 15, col = "forestgreen") +
  geom_hline(yintercept = 20, col = "forestgreen", linetype = "dashed") +
  geom_vline(xintercept = c(7,14,21,28), col = "grey") +
  scale_x_continuous(breaks=seq(0,28,7)) +
  scale_y_continuous(breaks=seq(0,30,5)) +
  labs(x = "Days",y="Proportion of deep sleep stage", title = "Deep sleep") 

Доля глубокого сна в зависимости от времени

Голова (Sleep.data)

> dput(head(Sleep.data))
structure(list(DATE = structure(c(1L, 4L, 7L, 10L, 13L, 16L), .Label = c("01-Dec-17", 
"01-Feb-18", "01-Jan-18", "02-Dec-17", "02-Feb-18", "02-Jan-18", 
"03-Dec-17", "03-Feb-18", "03-Jan-18", "04-Dec-17", "04-Feb-18", 
"04-Jan-18", "05-Dec-17", "05-Feb-18", "05-Jan-18", "06-Dec-17", 
"06-Feb-18", "06-Jan-18", "07-Dec-17", "07-Feb-18", "07-Jan-18", 
"08-Dec-17", "08-Jan-18", "09-Dec-17", "09-Feb-18", "09-Jan-18", 
"10-Dec-17", "10-Jan-18", "11-Dec-17", "11-Feb-18", "11-Jan-18", 
"12-Dec-17", "12-Jan-18", "13-Dec-17", "13-Feb-18", "13-Jan-18", 
"14-Dec-17", "14-Feb-18", "14-Jan-18", "15-Dec-17", "15-Jan-18", 
"16-Dec-17", "16-Jan-18", "17-Dec-17", "17-Jan-18", "18-Dec-17", 
"18-Jan-18", "19-Dec-17", "19-Jan-18", "20-Dec-17", "21-Dec-17", 
"21-Jan-18", "22-Dec-17", "22-Jan-18", "23-Dec-17", "23-Jan-18", 
"24-Dec-17", "24-Jan-18", "25-Dec-17", "25-Jan-18", "26-Dec-17", 
"26-Jan-18", "27-Dec-17", "27-Jan-18", "28-Dec-17", "28-Jan-18", 
"29-Dec-17", "29-Jan-18", "30-Dec-17", "30-Jan-18", "31-Dec-17", 
"31-Jan-18"), class = "factor"), DATEID = 1:6, MONTH = structure(c(1L, 
1L, 1L, 1L, 1L, 1L), .Label = c("Decembre", "Janvier", "Février"
), class = "factor"), DURATION = c(8.08, 7.43, 6.85, 6.23, 7.27, 
6.62), D.DEEP = c(1.67, 1.37, 1.62, 1.75, 1.95, 0.9), P.DEEP = c(17L, 
17L, 21L, 24L, 25L, 12L), STIMS = c(0L, 0L, 0L, 0L, 390L, 147L
), D.REM = c(1.7, 0.95, 0.95, 1.43, 1.47, 0.72), P.REM = c(17L, 
11L, 12L, 20L, 19L, 9L), D.LIGHT = c(4.7, 5.12, 4.27, 3.05, 3.83, 
4.98), P.LIGHT = c(49L, 63L, 55L, 43L, 49L, 66L), D.AWAKE = c(1.45, 
0.58, 0.47, 0.87, 0.37, 0.85), P.AWAKE = c(15L, 7L, 6L, 12L, 
4L, 11L), WAKE.UP = c(-2L, 0L, 2L, -1L, 3L, 1L), AGITATION = c(-1L, 
-3L, -1L, -2L, 2L, -1L), FRAGMENTATION = c(1L, -2L, 2L, 1L, 0L, 
-1L), PERIOD = structure(c(3L, 3L, 4L, 4L, 4L, 4L), .Label = c("HOLIDAYS", 
"SICK", "WE", "WORK"), class = "factor"), SPORT = structure(c(2L, 
1L, 2L, 2L, 2L, 1L), .Label = c("", "Day", "Evening"), class = "factor"), 
    ACTIVITY = structure(c(6L, 1L, 3L, 4L, 5L, 1L), .Label = c("", 
    "Bkool", "eBike", "Gym", "Natation", "Run"), class = "factor"), 
    TABLETS = c(0.5, 0.5, 0.5, 0.5, 0.5, 0.5), Ratio = c(1.15, 
    2.36, 3.45, 2.01, 5.27, 1.06), Sign = structure(c(2L, 2L, 
    2L, 2L, 2L, 2L), .Label = c("0", "1"), class = "factor"), 
    Sign.ratio = structure(c(2L, 2L, 2L, 2L, 2L, 2L), .Label = c("0", 
    "1"), class = "factor"), Sign.deep = structure(c(2L, 2L, 
    2L, 2L, 2L, 1L), .Label = c("0", "1"), class = "factor"), 
    Sign.awake = structure(c(1L, 2L, 2L, 1L, 2L, 1L), .Label = c("0", 
    "1"), class = "factor"), Sign.light = structure(c(2L, 1L, 
    1L, 2L, 2L, 1L), .Label = c("0", "1"), class = "factor"), 
    index = structure(c(1L, 1L, 1L, 1L, 2L, 1L), .Label = c("0", 
    "1"), class = "factor"), min = c(0, 0, 0, 0, 0, 0), max.WE = c(30, 
    30, 0, 0, 0, 0)), .Names = c("DATE", "DATEID", "MONTH", "DURATION", 
"D.DEEP", "P.DEEP", "STIMS", "D.REM", "P.REM", "D.LIGHT", "P.LIGHT", 
"D.AWAKE", "P.AWAKE", "WAKE.UP", "AGITATION", "FRAGMENTATION", 
"PERIOD", "SPORT", "ACTIVITY", "TABLETS", "Ratio", "Sign", "Sign.ratio", 
"Sign.deep", "Sign.awake", "Sign.light", "index", "min", "max.WE"
), row.names = c(NA, 6L), class = "data.frame")

1 Ответ

0 голосов
/ 17 февраля 2019

Спасибо за добавление данных, это упрощает понимание того, с чем вы работаете, и подтверждение того, что ответ действительно отвечает на ваш вопрос.

Я подумал, что было бы полезно создать отдельную таблицутолько начало и конец каждого смежного набора строк с одинаковыми PERIOD.Я сделал это, используя dplyr::case_when, предполагая, что мы должны пометить даты как «начало», если они являются первой строкой в ​​таблице (row_number () == 1), или они имеют значение PERIOD, отличное от предыдущей строки.Я отмечаю даты как «конец», если они являются последней строкой таблицы или имеют ИНИЦИАТИВНЫЙ ПЕРИОД, чем следующая строка.Я сохраняю только начало и конец, и выкладываю их в новые столбцы с именами start и end.

library(tidyverse)    
Period_ranges <- Sleep.data %>%
  mutate(period_status = case_when(row_number() == 1      ~ "start",
                               PERIOD != lag(PERIOD)  ~ "start",
                               row_number() == n()    ~ "end",
                               PERIOD != lead(PERIOD) ~ "end",
                               TRUE ~ "other")) %>%
filter(period_status %in% c("start", "end")) %>%
select(DATEID, PERIOD, period_status) %>%
mutate(PERIOD_NUM = cumsum(PERIOD != lag(PERIOD) | row_number() == 1)) %>%
spread(period_status, DATEID)

# Output based on sample data only. If there's a problem with the full data, please add more. To share full data, use `dput(Sleep.data)` or to share 20 rows use `dput(head(Sleep.data, 20))`.
>Period_ranges
   PERIOD PERIOD_NUM end start
 1     WE          1   2     1
 2   WORK          2   6     3

Теперь мы можем использовать это на графике.Если вы хотите переключить включение или скрипту с внешним видом отдельных типов PERIOD, вы можете изменить приведенный ниже код с помощью Period_ranges %>% filter(PERIOD == "WE"),

ggplot(Sleep.data, aes(x = DATEID)) +

  # Here I specify that this geom should use its own data.
  # I start the rectangles half a day before and end half a day after to fill the space.
  geom_rect(data = Period_ranges, inherit.aes = F,
            aes(xmin = start - 0.5, xmax = end + 0.5,
                ymin = 0, ymax = 30,
                fill = PERIOD), alpha = 0.5) +
  # Here we can specify the shading color for each type of PERIOD
  scale_fill_manual(values = c(
    "WE" = '#6495ED80',
    "WORK" = "gray60"
  )) +
  # rest of your code

Диаграмма на основе образца данных:

enter image description here

...