我有以下数据框 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 个混合频率序列。
有人可以帮我解决这个问题吗?
谢谢!
答案 0 :(得分: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" & !is.na(value)))
答案 1 :(得分:1)
在这种情况下,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
能够通过线性插值来近似值。在这种情况下,我假设已知值之间的线性插值适用于绘图(因为 geom_line
无论如何都在做)。查看 ?zoo::na.approx
了解更多详情,包括非线性插值。
zoo::na.approx(TS3, Date, na.rm = FALSE)
可以这样朗读:“我们想根据 TS3
的值来估算 NA
缺失时的值 (Date
),如果插值数据中仍有 NA
,则保留非 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
以获取替代方案(例如重复上次已知的观察)。