Iceberg Slim
Iceberg Slim

Reputation: 451

Forward looking time series filter

I have a time series of logical data. I am trying to find times when (a) the logical is false for that time; (b) the logical is false for the preceding three periods; and (c) the logical is false for the following two periods. For example in the following data frame only time 5 would meet the criteria.

example <- structure(list(time = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10), raining = c(TRUE, 
FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE)), .Names = c("time", 
"raining"), row.names = c(NA, -10L), class = "data.frame")

I can easily check the current time and the preceding three using filter

example$filtered <- filter(example[,"raining"], c(1,1,1,1), sides = 1) == 0

but I can't figure out how to get it to also look forward. Perhaps using sides = 2 and a different filter set? Any help is appreciated.

Upvotes: 3

Views: 340

Answers (2)

agstudy
agstudy

Reputation: 121598

I think you can reformulate the problem by looking for the point having 6 previous points equal to 0 then take 2 away from the index to get the desired result.

   000 0 00  <---> 00000 0  
   --- _ ++        ----- _

Here a solution using zoo package:

library(zoo)
dt = zoo(example$raining,order.by=example$time)
res <- rollsumr(dt, 6)  ## as commented below 
index(res[res==0])-2  
[1] 5

Using filter you can do this :

 filter(example[,"raining"], rep(1,6), sides = 1)==0

Upvotes: 3

Henrik
Henrik

Reputation: 67788

You may create offset versions of your vector using functions lead and lag in package dplyr

library(dplyr)
m <- cbind(sapply(3:1, function(x) lag(rain, x)),  # preceeding three
           rain,                                   # current 
           sapply(1:2, function(x) lead(rain, x))) # following two

# find row with all FALSE
which(rowSums(m, na.rm = TRUE) == 0)
# [1] 5

Upvotes: 2

Related Questions