更改ggplot中时间序列间隙的线型

Changing the line type of the gap in timeseries in ggplot

我有一个不规则间隔时间序列的水质测量值(通常每月测量一次,但不完全在每个月的同一天测量)。我用下面的代码在令人惊叹的 ggplot 中绘制了这些,用一条线连接所有测量值。

然而,当几个月没有进行测量时,也存在差距。我想用另一种线型或颜色绘制这些点之间的线(例如,如果间隔大于 60 天,则为虚线和灰色)。我需要为此拆分我的数据吗?我该如何处理?

library(ggplot2)
library(lubridate)

xdate <- as.Date(c(seq.POSIXt(ymd("2005-01-01"), ymd("2007-03-04"), by = "30 days"), 
           seq.POSIXt(ymd("2007-07-03"), ymd("2007-12-31"), by = "28 days"),
           seq.POSIXt(ymd("2008-05-15"), ymd("2010-10-10"), by = "25 days"),
           seq.POSIXt(ymd("2012-01-01"), ymd("2014-12-31"), by = "31 days")))

set.seed(321)                  
df <- data.frame(date = rep(xdate,3), par=rep(c("Cl","PO4","NO3")), y=rnorm(318,1,0.2))

ggplot(df, aes(x=date, y=y)) +
  geom_point(size=2) +
  geom_line() +
  facet_wrap(~par, nrow=3)

这应该会让你接近,

library(dplyr)
df <- df %>% group_by(par) %>% 
             arrange(date) %>% 
             mutate(gap = cumsum(c(0, diff(date) > 60)))
ggplot(df, aes(x=date, y=y, colour=factor(gap))) +
    geom_point(size=2) +
    geom_line() +
    facet_wrap(~par, nrow=3)

摆弄每个组的 ID 和 start/end 点应该能够将变量映射到线型。

在 baptiste 的帮助下,我找到了解决办法。也许数据操作可以更干净(欢迎提出建议),但它工作正常。

library(ggplot2)
library(lubridate)
library(dplyr)

#first some data
xdate <- as.Date(c(seq.POSIXt(ymd("2005-01-01"), ymd("2007-03-04"), by = "30 days"), 
           seq.POSIXt(ymd("2007-07-03"), ymd("2007-12-31"), by = "28 days"),
           seq.POSIXt(ymd("2008-05-15"), ymd("2010-10-10"), by = "25 days"),
           seq.POSIXt(ymd("2012-01-01"), ymd("2014-12-31"), by = "31 days")))
set.seed(321)                  
df <- data.frame(date = rep(xdate,3), par=rep(c("Cl","PO4","NO3")), y=rnorm(318,1,0.2))

# then calculate groups with dplyr (credits to @baptiste) 
df <- df %>% group_by(par) %>% 
  arrange(date) %>% 
  mutate(gap = cumsum(c(0, diff(date) > 60)))

# extract the first and the last of every group
thefirst <- 
  df %>% group_by(gap,par) %>% 
  arrange(date) %>% 
  summarise(first(date),first(y))
thelast <-
  df %>% group_by(gap,par) %>% 
  arrange(date) %>% 
  summarise(last(date),last(y))

# equalize colnames for rbind and ggplot
colnames(thefirst) <- colnames(thelast) <- colnames(df)[c(4,2,1,3)]

# add 1 to match with thelast of every group with the first of the next group
# and calculate max
thelast$gap <- thelast$gap+1
maxgap <- max(thelast$gap)

gaplines <- rbind(filter(thefirst, gap != 0), filter(thelast,gap != maxgap))

#ggplot the connected lines
(p <-
ggplot(df, aes(x=date, y=y)) +
  geom_point(size=2) +
  geom_line(aes(group=factor(gap))) +
  facet_wrap(~par, nrow=3))
# add the dotted lines
p +  geom_line(data=gaplines, aes(group = factor(gap)),linetype='dotted')

这给了我这张图: