Reputation: 451
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
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
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