How to Not Plot Gaps in Timeseries with R

How to not plot gaps in timeseries with R

You can add an additional variable, group, to your data frame indicating whether the difference between two dates is not equal to one day:

df.long$group <- c(0, cumsum(diff(df.long$Date) != 1))

ggplot(df.long, aes(x = Date, y = value, fill = variable,
order=desc(variable))) +
geom_area(position = 'stack', aes(group = group))

Sample Image


Update:

In order to remove the space between the groups, I recommend facetting:

library(plyr)
df.long2 <- ddply(df.long, .(variable), mutate,
group = c(0, cumsum(diff(Date) > 1)))

ggplot(df.long2, aes(x = Date, y = value, fill = variable,
order=desc(variable))) +
geom_area(position = 'stack',) +
facet_wrap( ~ group, scales = "free_x")

Sample Image

Plotting gaps in time series as zeroes in R and ggplot2

Following @AllanCameron comments, the issue needs to be resolved on the data level and not on the visualisation level. For that reason, the records which hold zero measurements must be manually and explicitly appended to the data or else they will be interpolated.

There is no way to make ggplot's geom_line show a zero where a record does not exist in the data even with a discrete x-axis, and while this makes sense for certain applications, it is not generalisable.

R Plotting time-series with time-gaps using facet_wrap

  1. It's often better to not use $ indexing within aes; this is especially true when you are using data=, a more idiomatic way would be geom_bar(data = Test1, aes(Date, G), ...).

  2. We can use cumsum(diff(Date) > .) to get groups by gaps, but it isn't clear where the gaps should be. For instance,

    table(diff(Test1$Date))
    # 1 15 26 83 247
    # 15 1 1 1 1
    table(diff(Test2$Date))
    # 1 4 5 7 62 185
    # 211 2 2 1 1 2

    You say "4 facets", but there is no gap-width that gives 4 facets in both datasets. I'll use Test2 and a gap width of 10, but this means Test1 will only fill three of the four facets.

Since we're faceting, we need to add some grouping variable to both datasets.

mindates <- by(Test2$Date, cumsum(c(TRUE, diff(Test2$Date) > 10)), 
min, simplify = FALSE)
mindates <- as.Date(unlist(mindates))
mindates
# 1 2 3 4
# "2017-01-01" "2017-09-01" "2018-01-01" "2018-09-01"
Test1$grp <- findInterval(Test1$Date, c(unlist(mindates), Inf), left.open = FALSE)
Test2$grp <- findInterval(Test2$Date, c(unlist(mindates), Inf), left.open = FALSE)ggplot() +
theme_gray() +
geom_bar(data = Test1, aes(x = Date, y = G), stat="identity", color = "red") +
geom_bar(data = Test2, aes(x = Date, y = G), stat="identity", color = "grey") +
scale_x_date(date_labels ="%m/%y",date_breaks = "1 month") +
facet_wrap(~ grp, scales = "free_x")

ggplot2 faceted plot

Time series plot in R: Remove gaps from plot [zoo]

As @Richard Telford suggested the gaps in the plot are due to missing data.
With base function complete.cases and na.locf from zoo the gaps
could be removed or filled with previous observations as below:

#to identity periods with missing data

missingPeriod = as.Date(index(ss[!complete.cases(ss),]))

#to retain only periods with no missing data
ssComplete = ss[complete.cases(ss),]

#to retain all periods with gaps filled with previous value
#maxgap parameter controls number of missing data replaced with prev observation
N = 5
ssFilled = zoo::na.locf(ss,maxgap=N);

#plots
plot.zoo(ssComplete , type = "o")

plot.zoo(ssFilled, type = "o")


Related Topics



Leave a reply



Submit