Порядок номеров недель как факторов в скользящих временных периодах

У меня есть красивый небольшой график, который отслеживает данные с течением времени. Данные охватывают последние 12 недель, собираются ежедневно, сгруппированы по неделям и выводятся еженедельно. Он работал безупречно до тех пор, пока изменение года не вытеснило мой фактор (неделю) из окна и не начал строить график 1-й недели 2019 перед 43-й неделей 2018 г. Как я могу автоматизировать уровни факторов при изменении порядка в новом году? Я могу вручную регулировать уровни фактора до 12 недели, но это похоже на бандаж. Это результат, которого я пытаюсь достичь без ручного вмешательства. введите описание изображения здесь

data <-  structure(list(ID = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
    1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 
    3L, 3L, 4L, 4L, 4L, 4L, 4L, 4L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 
    5L, 5L, 5L, 5L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 
    7L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 8L, 8L, 8L, 8L, 
    8L), .Label = c("58", "66", "68", "77", "79", "80", "84", "98"
    ), class = "factor"), Year = c(2019, 2019, 2019, 2018, 2018, 
    2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 
    2018, 2019, 2019, 2019, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 
    2018, 2018, 2018, 2018, 2018, 2019, 2019, 2019, 2018, 2018, 2018, 
    2018, 2018, 2018, 2018, 2018, 2018, 2019, 2019, 2019, 2018, 2018, 
    2018, 2018, 2018, 2018, 2018, 2018, 2018, 2019, 2019, 2019, 2018, 
    2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 
    2018, 2018), Week = c(1L, 2L, 3L, 43L, 44L, 45L, 46L, 47L, 48L, 
    49L, 50L, 51L, 43L, 44L, 45L, 46L, 47L, 1L, 2L, 3L, 46L, 47L, 
    48L, 49L, 50L, 51L, 44L, 45L, 46L, 47L, 48L, 49L, 1L, 2L, 3L, 
    43L, 44L, 45L, 46L, 47L, 48L, 49L, 50L, 51L, 1L, 2L, 3L, 43L, 
    44L, 45L, 46L, 47L, 48L, 49L, 50L, 51L, 1L, 2L, 3L, 43L, 44L, 
    45L, 46L, 47L, 48L, 49L, 50L, 51L, 43L, 44L, 45L, 46L, 47L), 
        Output = c(49.9, 67.42, 31.27, 65.8925, 79.2925, 103.47, 
        120.1125, 122.645, 109.3925, 91.3125, 81.06, 78.38, 119.13, 
        93.71, 149.74, 122.8775, 117.1075, 32.81, 29.49, 16.71, 42.8725, 
        60.6425, 71.2, 86.155, 78.6225, 81.605, 73.51, 84.42, 105.4, 
        74.515, 57.825, 42.8475, 11.26, 44.34, 22.83, 41.695, 75.77, 
        80.785, 118.175, 131.2875, 124.2375, 124.905, 85.7275, 61.7525, 
        188.23, 108.42, 42.42, 111.41, 79.8825, 70.4075, 72.695, 
        61.235, 58.7825, 47.9275, 46.5275, 48.1775, 11.09, 10.13, 
        0, 21.3375, 30.1275, 32.97, 53.51, 51.09, 40.385, 35.9025, 
        23.44, 21.1125, 111.94, 102.76, 105.71, 112.36, 115.7875)), class = "data.frame", row.names = c(NA, 
    -73L))

 ggplot(data, 
       aes(factor(Week,
                  levels = c(43, 44, 45, 46, 47, 48, 49, 50, 51, 1, 2, 3)),
           Output)) +
geom_line(size = 1.5, 
          aes(colour = ID,
              group = ID)) +
geom_point(aes(y = Output,
               colour = ID),
           size = 4,
           shape = 21,
           fill = "black",
           stroke = 2) + 
  labs(x = "Week Number",
       y = "output") +
  scale_y_continuous(breaks = pretty_breaks(n = 20),
                     limits = c(0, NA))

person Andrew M    schedule 17.01.2019    source источник
comment
Ближайшие мысли заключаются в том, чтобы изменить переменную недели на дату, а затем переформатировать дату в недели для меток оси. Я полагаю, что% W - это код формата.   -  person g_t_m    schedule 17.01.2019
comment
@g_t_m На самом деле это тоже было моим, думаю, я просто переборщил. Я думал, что есть способ добраться туда, не прибегая к датам, но оба эти решения работают хорошо.   -  person Andrew M    schedule 18.01.2019


Ответы (2)


В моем комментарии я изменил комбинацию недели / года на дату, создал график, а затем отформатировал ось x как неделю:

library(tidyverse)
library(lubridate)

data %>% 
  mutate(date = dmy(paste0("0101", Year)) + days(7*(Week)),
         date = floor_date(date, "weeks", week_start = 1)) %>%   # spoof week/year into date
  ggplot(aes(date, Output)) +
  geom_line(size = 1.5, 
            aes(colour = ID,
                group = ID)) +
  geom_point(aes(y = Output,
                 colour = ID),
             size = 4,
             shape = 21,
             fill = "black",
             stroke = 2) + 
  labs(x = "Week Number",
       y = "output") %>% 
  scale_x_date(date_breaks = "weeks", date_labels = "%W")

Надеюсь, у вас есть исходные даты, вместо того, чтобы переносить номер недели обратно в дату, поскольку это немного беспорядочно.

person g_t_m    schedule 17.01.2019

Для базового R рассмотрите возможность создания столбца даты, который включает форматирование года, а затем добавление соответствующей недели к преобразованной дате. Оттуда график с scale_x_date() отформатирован до номера недели:

data$Date <- with(data, as.Date(paste0(Year, "-01-01"), format="%Y-%m-%d", origin="1970-01-01") +
                               as.difftime(Week, unit="weeks")
             )

head(data)
#   ID Year Week   Output       Date
# 1 58 2019    1  49.9000 2019-01-08
# 2 58 2019    2  67.4200 2019-01-15
# 3 58 2019    3  31.2700 2019-01-22
# 4 58 2018   43  65.8925 2018-10-29
# 5 58 2018   44  79.2925 2018-11-05
# 6 58 2018   45 103.4700 2018-11-12

ggplot(data, 
       aes(Date,
           Output)) +
  geom_line(size = 1.5, 
            aes(colour = ID,
                group = ID)) +
  geom_point(aes(y = Output,
                 colour = ID),
             size = 4,
             shape = 21,
             fill = "black",
             stroke = 2) + 
  labs(x = "Week Number",
       y = "output") +
  scale_y_continuous(breaks = pretty_breaks(n = 20),
                     limits = c(0, NA)) +
  scale_x_date(breaks = pretty_breaks(n = 20),
                   labels = date_format("%W"))

Вывод графика номера недели

person Parfait    schedule 17.01.2019
comment
Спасибо за указатель на as.difftime как средство увеличения даты на недели. У меня за поясом новый инструмент. - person Andrew M; 18.01.2019