Can rollapply return a list of matrices?

隐身守侯 提交于 2019-12-05 10:33:35

After glancing at the rollapply.zoo code, I don't think there's a way to make it do what you want. Rolling your own function isn't that difficult though (pun intended).

rollcov <- function(x, width=10) {
  len <- NROW(x)
  add <- rep(1:(len-width)-1,each=width)
  seq.list <- split(rep(1:width,len-width)+add, add)
  lapply(seq.list, function(y) cov(x[y,]))
}

rollcov(data.list[[1]][,c("one","two","three")],10)
all <- lapply(data.list, function(x) rollcov(x[,c("one","two","three")],10))

I realized that I can trick rollapply into returning a vector, then bend that vector back into a matrix. The trick is using alply from the plyr package to bend the vector back into a matrix.

library("plyr")
library("zoo")
data.df <- data.frame(sic = rep(1:10, each = 40),
                      year = rep(1:40, len = 10*40),
                      one = rnorm(10*40),
                      two = 2*rnorm(10*40),
                      three = 3*rnorm(10*40))
data.list <- split(data.df, data$sic)
data.list <- lapply(data.list, zoo)
my.fun <- function(x) {
    x <- x[, c("one", "two", "three")]
    rollapply(x,
              width = 10, 
              function(x) as.vector(cov(x)),
              by.column = F, 
              align = "right")
}
my.fun.2 <- function(x) {
    alply(x, 1, matrix, nrow = sqrt(ncol(x)))
}
cov.list <- lapply(data.list, FUN = my.fun)
cov.list.2 <- lapply(cov.list, my.fun.2)

Or, for a list of arrays I can replace alply with aaply.

Remove the second data.list<- and modify my.fun so that given data.df we have the following (which is reasonably close to the original):

data.list <- split(data.df, data.df$sic)
my.fun <- function(x) {
    z <- zoo(x[, c("one", "two", "three")], x$year)
    ccov <- function(x) c(cov(x))
    r <- rollapplyr(z, width = 10, FUN = ccov, by.column = FALSE)
    toMat <- function(tt) matrix(r[tt], ncol(z))
    sapply(paste(time(r)), toMat, simplify = FALSE) # sapply(char,...) adds names
}
cov.list <- lapply(data.list, FUN = my.fun)

EDIT: Slight simplification.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!