#r #ggplot2
Вопрос:
У меня есть следующие таблицы данных x
:
x1 <- data.frame(Date = seq(as.Date("2010-01-01"),
as.Date("2012-12-01"),
by = "month"),
TS1 = rnorm(36,0,1),
TS2 = rnorm(36,0,1),
stringsAsFactors = F)
x2 <- data.frame(Date = seq(as.Date("2010-01-01"),
as.Date("2012-12-01"),
by = "quarter"),
TS3 = rnorm(12,0,1),
stringsAsFactors = F)
x <- left_join(x1, x2, by = "Date")
x
содержит две ежемесячные серии, в то время как одна-ежеквартальная.
Я хотел бы построить сюжет всех трех серий одновременно с ggplot
. Я осознаю dualplot
, как это можно сделать. Проблема с ним, однако, заключается в том, что он позволяет построить только 2 смешанных частотных ряда.
Есть ли кто-нибудь, кто может мне в этом помочь?
Спасибо!
Ответ №1:
Обратите внимание, что ggplot
требуется длинный формат, поэтому мы сначала используем tidyr::pivot_longer
.
Далее, мы можем построить график TS1
и TS2
легко, но TS3
не будем строить график вообще, так как он содержит пропущенные значения.
Один из вариантов-построить линию с пропусками с помощью отдельного geom_line
вызова:
x2 <- x %>%
tidyr::pivot_longer(cols = c(TS1, TS2, TS3), names_to = "TS") %>%
mutate(TS = as.factor(TS))
ggplot(x2, aes(x = Date, y = value, group = TS, color = TS))
geom_line()
geom_line(data = subset(x2, TS == "TS3" amp; !is.na(value)))
Комментарии:
1. отличное решение! Большое спасибо!
Ответ №2:
В этом случае ggplot
не требуется, чтобы данные были преобразованы в длинный формат (хотя это хорошее решение, если вы знакомы с преобразованием данных, и рекомендуется, особенно если нужно было построить много столбцов или отдельных строк).
Для простоты, особенно при обучении ggplot
, я могу предложить альтернативное решение.
TS1
и TS2
могут быть легко сопоставлены с датой, так как ни у NA
того, ни у другого нет значений. Здесь мы вызываем geom_line()
дважды, по одному для каждой линии:
x %>%
ggplot()
geom_line(aes(Date, TS1), colour = 'red')
geom_line(aes(Date, TS2), colour = 'blue')
Если вы попытаетесь включить третью geom_line()
с TS3
, будут нанесены только исходные две строки из TS3
-за пропущенных значений ( NA
). Решение состоит в том, чтобы заполнить NA
значения в данных перед построением графика, используя zoo::na.approx()
. Как следует из названия, zoo::na.approx()
способен приближать значения, когда у вас есть NA
s, с помощью линейной интерполяции. В этом случае я предполагаю, что линейная интерполяция между известными значениями подходит для построения графика (как geom_line
и в любом случае). Ознакомьтесь с ?zoo::na.approx
более подробной информацией, включая нелинейную интерполяцию.
zoo::na.approx(TS3, Date, na.rm = FALSE)
может быть прочитано вслух, например: «Мы хотим приблизить значения TS3
, когда они отсутствуют ( NA
), на основе значений Date
, и если в интерполированных данных все еще есть NA
s, сохраните NA
значения, которые мы можем приблизить».
x %>%
mutate(
TS3 = zoo::na.approx(TS3, Date, na.rm = FALSE)
) %>%
ggplot()
geom_line(aes(Date, TS1), colour = 'red')
geom_line(aes(Date, TS2), colour = 'blue')
geom_line(aes(Date, TS3), colour = 'green')
Обратите внимание, что зеленая линия заканчивается чуть короче (2 точки данных) двух других строк. Это связано с тем, что по умолчанию zoo::na.approx()
не выполняется интерполяция, когда NA
она не находится между двумя известными точками данных. Вот почему мы указали na.rm = FALSE
при выполнении интерполяции. Посмотрите на страницу справки ?zoo::na.approx
для поиска альтернатив (например, повторения последнего известного наблюдения).