Мне нужно визуализировать и сравнить разницу в двух одинаково длинных периодах продаж. 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")
Попробуй это. Вы можете отформатировать недельную переменную как фактор и сохранить желаемый порядок. Вот код:
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")
Выход:
Если вы хотите сохранить ось 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. Решение пока не найдено.
Еще один вариант — фасовать его. Это потребует объединения двух наборов в один с сохранением источника данных. (В любом случае, это обычно лучший способ справиться с этим в целом.)
(У меня нет 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.
Я согласен ... и я знаю, что иногда требуется прямое перекрытие, чтобы увидеть мельчайшие вертикальные различия между линиями. При этом мы немного теряем это измерение, хотя макро-различия должны быть очевидны — достаточно, учитывая те же ограничения по оси Y.
Ой, tibble::lst
, спасибо. Исправлено/замечено.
@r2evans Спасибо, ваше решение визуально самое чистое, но по характеру данных и покупателю =D Мне приходится использовать сравнение на одном графике, чтобы наглядно увидеть разницу в периодах продаж
Я думал, что это может быть так.
Спасибо, это отлично работает. Я пробовал что-то подобное. Я поставил неделю как фактор в ggplot, но это не сработало. Еще раз, спасибо