Zhubarb
Zhubarb

Reputation: 11895

R time series finding indices with sign change

I have a time series as below. I simply want to find the indices where the observations at t and t+1 have different signs.

Obviously, I can achieve this by getting the indices where t*(t-1)<0. However I am not sure about the best function to implement this logic.

What is the fastest way to achieve this in base R?

b <- structure(c(NA, NA, NA, NA, NA, NA, NA, NA, NA, 0.00117300000000009, 
            0.00165400000000004, 0.00262999999999991, 0.00236499999999995, 
            0.00571200000000016, 0.00364100000000001, 0.0013479999999999, 
            -0.0013510000000001, -0.00270499999999996, -0.00338699999999981, 
            -0.000166000000000111, -0.00105099999999991, -0.002467, -0.00367300000000004, 
            -0.00569500000000001, -0.00446499999999994, -0.002861, -0.00129699999999988, 
            0.000721000000000194, 0.00351799999999969, 0.0040929999999999, 
            0.00418700000000016, 0.004189, 0.00348199999999999, 0.0015729999999996, 
            5.89999999998092e-05, -0.000866000000000255, -0.00130799999999986, 
            0.00158199999999997, 0.00198000000000009, 0.00180899999999995, 
            0.000526999999999944, -0.000598000000000098, -0.00189899999999987, 
            -0.00285700000000011, -0.00296200000000013, -0.000966000000000244, 
            0.00388200000000016, 0.00311499999999998, 0.00300600000000006
), .Tsp = c(1, 49, 1), class = "ts")

Upvotes: 1

Views: 97

Answers (1)

Dirk is no longer here
Dirk is no longer here

Reputation: 368251

You can probably do that with ts objects as well, but I work much more with zoo or xts. So here is a simple solution for zoo:

R> suppressMessages(library(zoo))
R> bz <- as.zoo(b)
R> bz[which(c(NA,diff(sign(bz))) != 0)]
       17        28        36        38        42        47 
-0.001351  0.000721 -0.000866  0.001582 -0.000598  0.003882 
R> 

Edit: Similarly, to get just the index you can use a convenience accessor provided by zoo:

R> index(bz[which(c(NA,diff(sign(bz))) != 0)])
[1] 17 28 36 38 42 47
R> 

Edit 2: If you really wanted to stick with ts objects and base R, reconstruct the index series via tsp() and use that:

R> tsp(b)[1] + which(diff(sign(b)) != 0) * tsp(b)[3]
[1] 17 28 36 38 42 47
R> 

Upvotes: 6

Related Questions