R - non-linear filter for the time series - filter, lappel or loop?

I have a vector containing simple time series data (extracted from the deSolve matrix), which for testing purposes can be:

x <- c(1, 2, 3, 4, 5) 

and would like to apply a nonlinear filter

 x[n]*x[n]-x[n-1]*x[n+1] 

to all elements of the vector except the first and last elements, because the filter cannot be applied to these two elements (for example, when the term x[n-1] meets the first element or the term x[n+1] meets the last element). This is my problem.

Things I tried: 1) The filter() ) command expects a linear filter (i.e., Without multiplying filter coefficients). 2) lapply() requires that this function is applicable to all elements of the list.

Is a cycle the only alternative?

Thanks for your help, Carey

+4
source share
2 answers

You can do this with a loop, or apply or vectorize.

 > x <- c(1, 2, 3, 4, 5) > r <- NA > for (n in 2:length(x)) r[n] <- x[n]*x[n]-x[n-1]*x[n+1] > (r) [1] NA 1 1 1 NA > > r <- NA > lapply(2:length(x),function(n) r[n] <<- x[n]*x[n]-x[n-1]*x[n+1]) [[1]] [1] 1 [[2]] [1] 1 [[3]] [1] 1 [[4]] [1] NA > (r) [1] NA 1 1 1 NA > r <- NA > r <- x^2 - c(NA,x[1:(length(x)-1)]) * c(x[2:length(x)],NA) > (r) [1] NA 1 1 1 NA 

vectorization is the most efficient, but harder to decrypt the code

 > x <- runif(50000) > > r <- NA > system.time(for (n in 2:length(x)) r[n] <- x[n]*x[n]-x[n-1]*x[n+1]) user system elapsed 8.55 0.01 8.58 > > r <- NA > system.time(lapply(2:length(x),function(n) r[n] <<- x[n]*x[n]-x[n-1]*x[n+1])) user system elapsed 11.36 0.00 11.39 > > r <- NA > system.time(r <- x^2 - c(NA,x[1:(length(x)-1)]) * c(x[2:length(x)],NA)) user system elapsed 0.01 0.00 0.01 
+4
source

1) Try rollapply in the zoo package:

 > library(zoo) > rollapply(zoo(1:5), 3, function(x) x[2] * x[2] - x[1] * x[3]) 2 3 4 1 1 1 

coredata(z) gives part of the data, i.e. c(1, 1, 1) , and time(z) gives the time part, i.e. c(2, 3, 4) .

2) Another way to do this at the zoo:

 > z <- zoo(1:5) > z*z - lag(z) * lag(z,-1) 2 3 4 1 1 1 

3) This last approach also works in the ts class found in the core R:

 > tt <- ts(1:5) > tt * tt - lag(tt) * lag(tt, -1) Time Series: Start = 2 End = 4 Frequency = 1 [1] 1 1 1 
+3
source

Source: https://habr.com/ru/post/1341553/


All Articles