Ggplot2 сравнение периода времени

Мне нужно визуализировать и сравнить разницу в двух одинаково длинных периодах продаж. 2018/2019 и 2019/2020. Оба периода начинаются на 44-й неделе и заканчиваются на 36-й неделе следующего года. Если я создаю график, оба периода непрерывны и выстраиваются в линию. Если я использую только номер недели, значения сортируются как континуум, и график не имеет смысла. Можете ли вы придумать решение?

Спасибо

Данные:

set.seed(1)
df1 <- data.frame(sells = runif (44),
                  week = c(44:52,1:35),
                  YW = yearweek(seq(as.Date("2018-11-01"), as.Date("2019-08-31"), by = "1 week")),
                  period = "18/19")

df2 <- data.frame(sells = runif (44),
                  week = c(44:52,1:35),
                  YW = yearweek(seq(as.Date("2019-11-01"), as.Date("2020-08-31"), by = "1 week")),
                  period = "19/20")

# Yearweek on x axis, when both period are separated

ggplot(df1, aes(YW, sells)) +
  geom_line(aes(color = "Period 18/19")) + 
  geom_line(data=df2, aes(color = "Period 19/20")) +
  labs(color = "Legend text")

# week on x axis when weeks are like continuum and not splited by year
ggplot(df1, aes(week, sells)) +
  geom_line(aes(color = "Period 18/19")) + 
  geom_line(data=df2, aes(color = "Period 19/20")) +
  labs(color = "Legend text")
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
215
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Попробуй это. Вы можете отформатировать недельную переменную как фактор и сохранить желаемый порядок. Вот код:

library(ggplot2)
library(tsibble)
#Data
df1$week <- factor(df1$week,levels = unique(df1$week),ordered = T)
df2$week <- factor(df2$week,levels = unique(df2$week),ordered = T)
#Plot
ggplot(df1, aes(week, sells)) +
  geom_line(aes(color = "Period 18/19",group=1)) + 
  geom_line(data=df2, aes(color = "Period 19/20",group=1)) +
  labs(color = "Legend text")

Выход:

Спасибо, это отлично работает. Я пробовал что-то подобное. Я поставил неделю как фактор в ggplot, но это не сработало. Еще раз, спасибо

Eischias 14.12.2020 14:13
Ответ принят как подходящий

Если вы хотите сохранить ось x в виде числовой шкалы, вы можете сделать:

ggplot(df1, aes((week + 9) %% 52, sells)) +
  geom_line(aes(color = "Period 18/19")) + 
  geom_line(data=df2, aes(color = "Period 19/20")) +
  scale_x_continuous(breaks = 1:52,
                     labels = function(x) ifelse(x == 9, 52, (x - 9) %% 52), 
                     name = "week") +
  labs(color = "Legend text")

Я работаю с вашим решением, но я заметил одну вещь. По оси X вместо 52 указано 0. Решение пока не найдено.

Eischias 14.12.2020 15:15

Еще один вариант — фасовать его. Это потребует объединения двух наборов в один с сохранением источника данных. (В любом случае, это обычно лучший способ справиться с этим в целом.)

(У меня нет tstibble, поэтому у моего YW просто есть seq(...), нет yearweek. Это должно переводиться.)

ggplot(dplyr::bind_rows(tibble::lst(df1, df2), .id = "id"), aes(YW, sells)) +
  geom_line(aes(color = id)) +
  facet_wrap(id ~ ., scales = "free_x", ncol = 1)

Вместо dplyr::bind_rows можно также использовать data.table::rbindlist(..., idcol = "id") или do.call(rbind, ...), хотя в последнем случае вам нужно будет назначить id извне.

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

... +
  scale_x_date(labels = function(z) format(z, "%Y-%m"))

Хотя маловероятно, что вы можете сделать это без наличия tibble::lst, вы можете заменить его на list(df1=df1, df2=df2) или что-то подобное.

Да, я думаю, что это самое приятное для глаз и имеет самую четкую маркировку по оси X.

Allan Cameron 14.12.2020 14:29

Я согласен ... и я знаю, что иногда требуется прямое перекрытие, чтобы увидеть мельчайшие вертикальные различия между линиями. При этом мы немного теряем это измерение, хотя макро-различия должны быть очевидны — достаточно, учитывая те же ограничения по оси Y.

r2evans 14.12.2020 14:33

Ой, tibble::lst, спасибо. Исправлено/замечено.

r2evans 14.12.2020 14:37

@r2evans Спасибо, ваше решение визуально самое чистое, но по характеру данных и покупателю =D Мне приходится использовать сравнение на одном графике, чтобы наглядно увидеть разницу в периодах продаж

Eischias 14.12.2020 14:40

Я думал, что это может быть так.

r2evans 14.12.2020 14:41

Другие вопросы по теме