计算滚动窗口协方差矩阵

3

我希望您能帮忙翻译一下关于it技术的内容。以下是需要翻译的内容:

我正在尝试计算一组资产的滚动窗口(每天移动1次)协方差矩阵。

假设我的数据框如下:

df <- data.frame(x = c(1.5,2.3,4.7,3,8.4), y =c(5.3,2.4,8.4,1.3,2.5),z=c(2.5,1.3,6.5,4.3,2.8),u=c(1.1,2.5,4.3,2.5,6.3))

我期望输出结果如下:

我期望输出结果如下:

cov(df[1:3,])  :

         x        y        z        u
x 2.773333 3.666667 4.053333 2.613333
y 3.666667 9.003333 7.846667 2.776667
z 4.053333 7.846667 7.413333 3.413333
u 2.613333 2.776667 3.413333 2.573333



cov(df[2:4,])  :

         x         y        z    u
x 1.523333  4.283333 3.053333 1.23
y 4.283333 14.603333 7.253333 3.93
z 3.053333  7.253333 6.813333 2.22
u 1.230000  3.930000 2.220000 1.08



cov(df[3:5,])  :

           x          y         z          u
x  7.6233333 -0.5466667 -3.008333  5.1633333
y -0.5466667 14.4433333  5.941667  0.9233333
z -3.0083333  5.9416667  3.463333 -1.5233333
u  5.1633333  0.9233333 -1.523333  3.6133333

但是由于数据集中有很多行,所以所有内容都在一个循环中进行了...

  1. 如果我想通过将滚动窗口向前移动1天来按滚动基础计算协方差矩阵,可能的for循环会是什么样子?或者我应该使用一些apply函数族?

  2. 如果我想要为上面的循环创建时间序列对象,哪种时间序列类会更合适?现在我使用了fPortfolio包中的as.timeSeries

我就是无法理解...

最好的问候


请展示您期望的输出结果。 - Josh O'Brien
1个回答

6
为创建滚动窗口,你可以使用 embed
## your data.frame
df <- data.frame(x=c(1.5,2.3,4.7,3,8.4), y=c(5.3,2.4,8.4,1.3,2.5), z=c(2.5,1.3,6.5,4.3,2.8), u=c(1.1,2.5,4.3,2.5,6.3))

## define windows
windowSize <- 3
windows <- embed(1:nrow(df), windowSize)

lapplyApproach <- function(df, windows) {
    ## convert window matrix to a list
    windowsList <- split(t(windows), rep(1:nrow(windows), each=ncol(windows)))
    ## edit: customize names: "from:to"
    names(windowsList) <- unlist(lapply(windowsList, function(x)paste(range(x), sep="", collapse=":")))
    return(lapply(windowsList, function(x)cov(df[x, ])))
}

forApproach <- function(df, windows) {
    l <- vector(mode="list", length=nrow(windows))
    for (i in 1:nrow(windows)) {
        l[[i]] <- cov(df[windows[i, ], ])
    }
    return(l)
}

## check results
all.equal(forApproach(df, windows), unname(lapplyApproach(df, windows)))
# TRUE

## test running time
library("rbenchmark")

## small example
benchmark(lapplyApproach(df, windows), forApproach(df, windows), order="relative")
#                         test replications elapsed relative user.self sys.self user.child sys.child
#2    forApproach(df, windows)          100   0.075     1.00     0.072        0          0         0                                                                          
#1 lapplyApproach(df, windows)          100   0.087     1.16     0.084        0          0         0

## a larger one
n <- 1e3
df <- data.frame(x=rnorm(1:n), y=rnorm(1:n), z=rnorm(1:n), u=rnorm(1:n))
windows <- embed(1:nrow(df), windowSize)
benchmark(lapplyApproach(df, windows), forApproach(df, windows), order="relative")
#                         test replications elapsed relative user.self sys.self user.child sys.child
#1 lapplyApproach(df, windows)          100  26.386    1.000    26.301    0.004          0         0                                                                          
#2    forApproach(df, windows)          100  26.932    1.021    26.838    0.000          0         0

编辑:对于时间序列,您可以使用软件包xts及其函数endpointsperiod.applyapply.daily等。


非常感谢!非常感激 :) - user1665355
你有没有好的解决方案,可以“重命名”计算出的协方差矩阵?例如,将$3291更改为“2011-01-01至2011-02-30”之类的名称。此致敬意。 - user1665355
如果这个答案解决了你的问题,请@user1665355标记该问题已回答。 - sgibb
你有没有关于如何创建滚动窗口的干净建议?与其向前滚动1天,不如滚动间隔时间。比如说,使用60天的数据来创建协方差矩阵。然后,在60天之后计算下一个cov.matrix。再次感谢你:) - user1665355
@user1665355 增加 windowSize?! - sgibb
抱歉,问题有点傻。现在正在尝试将日期分配给名称。我想为每个协方差矩阵获取日期范围,而不是观察编号的范围。具体来说,我想要类似于$1999-02-26:2011-12-30而不是$1:60的东西。我正在尝试将日期范围分配给windowsList,但它无法正常工作。请给我一个关于如何做的想法 :) - user1665355

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接