2012-09-13 80 views
3

我正在計算一些資產的滾動窗口(移動1天)協方差矩陣。計算滾動窗口協方差矩陣

說我DF看起來是這樣的:

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. 如何可能for循環看起來像我想計算通過將滾動窗口移動1天,滾動處理協方差矩陣?或者我應該使用一些apply家庭功能?

  2. 如果我想爲上面的循環創建一個時間序列對象,那麼什麼時間序列類更適合?現在我使用fPortfolio包中的as.timeSeries

我根本無法得到它...

問候

+0

請出示你所期望的輸出樣子。 –

+0

對不起,現在加入:) – user1665355

回答

5

要創建滾動窗口,你可以使用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,...

+0

非常感謝!欣賞它:) – user1665355

+0

你有什麼好的解決方案,我可以「重命名」計算的協方差矩陣。例如,而不是$「3291」,如「2011-01-01至2011年02月30日」?最好的問候 – user1665355

+0

@ user1665355看到我的編輯在'lapplyApproach'作爲例子。 – sgibb