问题
I have 3 time series which I can apply the wavelet transform to using a rolling window. The rolling window takes a single time series of length 200 and applies the waveslim::modwt
function to it over the first 30 samples. This outputs 5 lists of which I am only interested in (d1,d2,d3,d4) and these each have a length of 30. A simple example can be found here:
library(waveslim)
J <- 4 #no. of levels in decomposition
data(ar1)
ar1.modwt <- modwt(ar1, "la8", J)
@G. Grothendieck has kindly provided a neat piece of code for the rolling window approach for a single time series here.
The rolling window increments by 1 and we go again, producing another 5 lists of which I only care for d1->d4 and so on and so on until the full length of the time series had been rolled over.
The next step is to apply the waveslim::brick.wall
function to the output of the rolling window lists. The brick.wall
function looks at the output of modwt
for the first window across the 4 levels and replaces some of the values with NA
s.
I believe I have covered this by modifying @G. Grothendieck answer using the following approach, I hope I am right:
modwt2 <- function(...) unlist(head(brick.wall(modwt(...)), 4))
rollr <- rollapplyr(ar1, 30, FUN = modwt2, wf = "la8", n.levels = 4, boundary = "periodic")
L <- lapply(1:nrow(rollr), function(i) matrix(rollr[i,], , 4))
The final piece is to construct correlation matrices for the outputs of the brick.wall
function which is L
above over the 4 levels of interest.
There is a function called waveslim::wave.correlation
which takes two brick.wall
outputs X and Y and computes the wave.correlation
over the various levels.
library(waveslim)
data(exchange)
returns <- diff(log(as.matrix(exchange)))
returns <- ts(returns, start=1970, freq=12)
wf <- "la8"
J <- 4
demusd.modwt <- modwt(returns[,"DEM.USD"], wf, J)
demusd.modwt.bw <- brick.wall(demusd.modwt, wf)
jpyusd.modwt <- modwt(returns[,"JPY.USD"], wf, J)
jpyusd.modwt.bw <- brick.wall(jpyusd.modwt, wf)
returns.modwt.cor <- wave.correlation(demusd.modwt.bw, jpyusd.modwt.bw,
N = dim(returns)[1])
I wish to expand on this and compute the full correlation matrix for my 3 time series. Please note that the example above with exchange rates does not use the rolling window approach as it uses the full length of the time series which I would like to now do and it also produces a single value for the correlation between two time series. It does not construct the full correlation matrix which I need as I am interested in the eigenvalues of these correlation matrices over time.
So in summary:
- Take 3 time series
- Apply
modwt
function using rolling window - Apply
brick.wall
function to each output of the rolling window in 2 above - Create full 3x3 correlation matrix for the 4 levels using outputs of 3 above over time
回答1:
Putting together the pieces you give in your question:
1) Create 3 time series
set.seed(1)
s <- replicate(3, rnorm(200), simplify = FALSE)
2) & 3) Apply modwt
and brick.wall
with rolling window
modwt2 <- function(...) unlist(head(brick.wall(modwt(...), wf = "la8"), 4))
rollr <- lapply(s, function(x) rollapplyr(x, 30, FUN = modwt2, wf = "la8",
n.levels = 4, boundary = "periodic"))
L <- lapply(rollr, function(x) lapply(1:nrow(x), function(i) matrix(x[i,], , 4)))
res <- lapply(L, function(y) lapply(y, function(x) as.list(as.data.frame(x))))
4) Create correlation matrices
create_4mat <- function(w) {
# create four 3*3 correlation matrices (one for each level) for window w
M <- replicate(4, matrix(0, nrow = 3, ncol = 3), simplify = FALSE)
for (k in 1:4) {
for (i in 1:3) {
for (j in (i:3)[-1]) {
M[[k]][i, j] = wave.correlation(res[[i]][[w]], res[[j]][[w]], N=30)[k, 1]
}
}
M[[k]] <- M[[k]] + t(M[[k]]) + diag(1, 3, 3)
}
M
}
output <- lapply(1:171, create_4mat)
output
is a list of 171 lists of 4 correlations matrices.
For instance, output[[28]][[2]]
is the correlation matrix for d2
in the 28th window:
output[[28]][[2]]
# [,1] [,2] [,3]
# [1,] 1.0000000 -0.1740320 0.2292872
# [2,] -0.1740320 1.0000000 0.6046918
# [3,] 0.2292872 0.6046918 1.0000000
Edit: Eigenvalues (as requested in comment)
For d1
:
eigenvalues1 <- lapply(output, function(x) eigen(x[[1]], symmetric = TRUE,
only.values = TRUE)$values)
Similarly for d2
. Note that for d3
and d4
all correlation matrices are filled with missing values.
来源:https://stackoverflow.com/questions/45673142/wavelet-correlation-using-rolling-window