Hello and apologies for asking this, as I think variations on the question have been answered many times, but I cannot seem to apply those to my specific problem.
I have a huge time series of stock returns of many different companies that looks something like this
library(tidyquant)
library(PerformanceAnalytics)
df = data.frame(tq_get("AAPL"))
ts = df[ , 3:8] %>%
xts(order.by = as.Date(df[ , 2], "%Y-%m-%d")) %>%
Return.calculate()
Now I need to do rolling correlations of each column with each other column in my time series. For just two columns the following works perfectly
rollcor = rollapply(ts, 63, function(x) cor(x[ , 1],x[ , 2]), by.column=FALSE)
But I cannot get it to work with apply()
over columns, so I tried a for loop to correlate at least the first column with all the others
rollcors = data.frame(ts)
for(j in ncol(rollcors)) {
rollcors[ , j] = rollapply(rollcors, 63, function(x) cor(x[ , 1],x[ , j]), by.column=FALSE, fill = NA)
}
But this doesn't replace each column with a new one containing correlations like I hoped it would.
I'd also prefer to keep the output vertically oriented like it is now, for better readability. My perfect result would be a list of dataframes/time series, each containing the correlations of one column with all other columns, which I could then furter manipulate (daily medians, etc.).
This provides the correlation matrix unravelled into a row for each date. There will be n*n columns where ts has n columns:
r1 <- rollapplyr(ts, 63, cor, fill = NA, by.column = FALSE)
or this will show only the lower triangle and will have choose(n, 2) columns:
ccor <- function(x) { cc <- cor(x); cc[lower.tri(cc)] }
r2 <- rollapplyr(X, 63, ccor, fill = NA, by.column = FALSE)
This can be used to assign column names, if needed.
paste_ <- function(...) paste(..., sep = "_")
names_mat <- do.call("outer", list(names(ts), names(ts), paste_))
names(r1) <- names_mat
names(r2) <- names_mat[lower.tri(names_mat)]