Using apply (or sapply) on an mts object removes its time series properties when sending to function. How should I apply same function (with ts input and ts output) on each of times series in an mts object and return it (preferably as mts) [I mean besides using for loops]?
For example suppose I write a function that returns the trend of a time series (using stl)
myfunc <- function(x) {
return(stl(x,"per")$time.series[,2])
}
Now for a sample mts
z <- ts(matrix(rnorm(90), 30, 3), start=c(1961, 1), frequency=4)
class(z)
Sending only one of the time series works correct:
myfunc(z[,1]) # works correctly, returns the trend of first series
My function is not designed for multiple time series so:
myfunc(z) # will not work returning the error below
Error in stl(x, "per") : only univariate series are allowed
Using apply on the mts object send each of the time series as a vector, not preserving its time series properties (tsp):
apply(z,2,myfunc) # will not work returning the error below
Error in stl(x, "per") :
series is not periodic or has less than two periods
A simple way around this, is to work with the indices instead of a clean apply
:
sapply(seq_len(ncol(z)),function(i) myfunc(z[,i]))
apply
puts clean vectors inside the function, because it first converts an object to a matrix. By using the [
function defined for time series objects, you are sure that you extract a valid time series each time.
I change the myfunc to check if it have a ts object as parameter x.
If x is not a ts , it is converted to ts object as stl need this parameter type.
myfunc <- function(x,...){
y <- x
if(class(x) != 'ts') {
dots <- c(...)
y <- ts(x,start=c(dots[1], dots[2]), frequency=dots[3])
}
return(stl(y,"per")$time.series[,2])
}
## no need to conversion (already ts object)
myfunc(z[,1])
## mts object ( here we give parameter necessary for conversion)
apply(z,2,myfunc,1961,1,4)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With