2012-02-19 16 views
9

ローリングウィンドウ回帰を実行したいが、lmを使用する定義済みの関数でrollapplyが機能しない5通貨ペアの毎日1033回の返品ポイントがある()。XTSシリーズにローリングウィンドウ回帰を適用するR

> lm(USDZAR ~ ., data = fxr)$coefficients 
    (Intercept)  USDEUR  USDGBP  USDCHF  USDCAD 
-1.309268e-05 5.575627e-01 1.664283e-01 -1.657206e-01 6.350490e-01 

は、しかし、私はローリング62日ウィンドウを実行したい:私は簡単に他のペアに対してUSDZARをモデル化するためにデータセット全体のためにそれにLMを実行することができます

> head(fxr) 
       USDZAR  USDEUR  USDGBP  USDCHF  USDCAD 
2007-10-18 -0.005028709 -0.0064079963 -0.003878743 -0.0099537170 -0.0006153215 
2007-10-19 -0.001544470 0.0014275520 -0.001842564 0.0023058211 -0.0111410271 
2007-10-22 0.010878027 0.0086642116 0.010599365 0.0051899551 0.0173792230 
2007-10-23 -0.022783987 -0.0075236355 -0.010804304 -0.0041668499 -0.0144788687 
2007-10-24 -0.006561223 0.0008545792 0.001024275 -0.0004261666 0.0049525483 
2007-10-25 -0.014788901 -0.0048523001 -0.001434280 -0.0050425302 -0.0046422944 

> tail(fxr) 
       USDZAR  USDEUR  USDGBP  USDCHF  USDCAD 
2012-02-10 0.018619309 0.007548205 0.005526184 0.006348533 0.0067151342 
2012-02-13 -0.006449463 -0.001055966 -0.002206810 -0.001638002 -0.0016995755 
2012-02-14 0.006320364 0.006843933 0.006605875 0.005992935 0.0007001751 
2012-02-15 -0.001666872 0.004319096 -0.001568874 0.003686840 -0.0015009759 
2012-02-16 0.006419616 -0.003401364 -0.005194817 -0.002709588 -0.0019044761 
2012-02-17 -0.004339687 -0.003675992 -0.003319899 -0.003043481 0.0000000000 

:ここに私のデータであり、時間をかけてこれらの係数の進化を取得するので、私はこれを行う関数dolmを作成します。私はこの上rollapply実行すると

> dolm 
function(x) { 
    return(lm(USDZAR ~ ., data = x)$coefficients) 
} 

は、しかし、私は、次を得る:

細かい自身の作品でさえdolm(FXR)にもかかわらずである
> rollapply(fxr, 62, FUN = dolm) 
Error in terms.formula(formula, data = data) : 
    '.' in formula and no 'data' argument 

は:

> dolm(fxr) 
    (Intercept)  USDEUR  USDGBP  USDCHF  USDCAD 
-1.309268e-05 5.575627e-01 1.664283e-01 -1.657206e-01 6.350490e-01 

はここで何が起こっているの?

> dolm <- edit(dolm) 
> dolm 
function(x) { 
    return(mean(x)) 
} 
> rollapply(fxr, 62, FUN = dolm) 
        USDZAR  USDEUR  USDGBP  USDCHF  USDCAD 
2007-11-29 -1.766901e-04 -6.899297e-04 6.252596e-04 -1.155952e-03 7.021468e-04 
2007-11-30 -1.266130e-04 -6.512204e-04 7.067767e-04 -1.098413e-03 7.247315e-04 
2007-12-03 8.949942e-05 -6.406932e-04 6.637066e-04 -1.154806e-03 8.727564e-04 
2007-12-04 2.042046e-04 -5.758493e-04 5.497422e-04 -1.116308e-03 7.124593e-04 
2007-12-05 7.343586e-04 -4.899982e-04 6.161819e-04 -1.057904e-03 9.915495e-04 

すべてのヘルプははるかに高く評価:dolmは、例えばシンプルな機能が意味であれば正常に動作するようです。基本的に私が望むのは、ローリング62日間のウィンドウでUSDZAR〜USDEUR + USDGBP + USDCHF + USDCADの回帰の重み付けをすることです。

答えて

9

いくつかの問題がここにあります

  • rollapplyは行列を渡しますが、lmdata.frameが必要です。
  • rollapplyは、 by.column=FALSEを指定しない限り、各列に別々に関数を適用します。我々は上記の組み込み

1)

dolm <- function(x) coef(lm(USDZAR ~ ., data = as.data.frame(x)))) 
rollapplyr(fxr, 62, dolm, by.column = FALSE) 

あなたがrollapplyrを使用しない場合

  • あなたは、または日付に合わせ 右のように結果をしたいが、ない場合があります2)上記のdolmlmの代わりに、lm.fitを使用すると、マトリックスで直接動作し、高速です。

    dolm <- function(x) coef(lm.fit(cbind(Intercept = 1, x[,-1]), x[,1])) 
    
  • +0

    よろしくお願いいたします。はい、私はちょうど周りを遊んだ後にもそれを働いた。愚かな私。 by.column =もちろんFALSE! ありがとうございました。あなたの動物園の文書を読んでいただけです。素晴らしいもの。 私は、rollapplyがちょっと混乱しているのは、lm()がxts全体で動作するのに対し、rollapply()によって返された部分ではないことです。ある人が、rollapplyがまだlm()の下で動作する別のxtsを返すことを合理的に期待していたかもしれません。 しかし、by.columnのMea culpaは偽です。その言い訳はありません。 –

    +0

    見逃しているのは、 'rollapply'はxtsの一部ではありませんが、動物園の一部であり、' rollapply.zoo'を送出していることです。 –

    +0

    これを明確にしていただきありがとうございます。 (fxr) > fxr < - zoo(fxr) > class(fxr) [1] "zoo" > rollapply(fxr、62、function(x)coef(lm(USDZAR〜x、data = x))、 by.column = FALSE)model.frame.defaultで エラー(式= USDZAR〜X、データ= xで、drop.unused.levels = TRUE): 'データ' でなければならないdata.frameなく、マトリックス又は配列 私たちはまだこの問題を抱えています。私は理解しています... Rにはこの種の問題がたくさんありますが、まだまだです。私たちがここで持っているのは、動物園全体のオブジェクトで動作しますが、ロールアプリケーションのサブセットでは動作しません。 –

    1

    第3のオプションは、以下のコードで行われるようにQR分解でR行列を更新することです。上記の解決策は、あなたがmodel.matrixmodel.response最初を形成することが必要です

    library(SamplerCompare) # for LINPACK `chdd` and `chud` 
    roll_coef <- function(X, y, width){ 
        n <- nrow(X) 
        p <- ncol(X) 
        out <- matrix(NA_real_, n, p) 
    
        is_first <- TRUE 
        i <- width 
        while(i <= n){ 
        if(is_first){ 
         is_first <- FALSE 
         qr. <- qr(X[1:width, ]) 
         R <- qr.R(qr.) 
    
         # Use X^T for the rest 
         X <- t(X) 
    
         XtY <- drop(tcrossprod(y[1:width], X[, 1:width])) 
        } else { 
         x_new <- X[, i] 
         x_old <- X[, i - width] 
    
         # update R 
         R <- .Fortran(
         "dchud", R, p, p, x_new, 0., 0L, 0L, 
         0., 0., numeric(p), numeric(p), 
         PACKAGE = "SamplerCompare")[[1]] 
    
         # downdate R 
         R <- .Fortran(
         "dchdd", R, p, p, x_old, 0., 0L, 0L, 
         0., 0., numeric(p), numeric(p), integer(1), 
         PACKAGE = "SamplerCompare")[[1]] 
    
         # update XtY 
         XtY <- XtY + y[i] * x_new - y[i - width] * x_old 
        } 
    
        coef. <- .Internal(backsolve(R, XtY, p, TRUE, TRUE)) 
        out[i, ] <- .Internal(backsolve(R, coef., p, TRUE, FALSE)) 
    
        i <- i + 1 
        } 
    
        out 
    } 
    
    # simulate data 
    set.seed(101) 
    n <- 1000 
    wdth = 100 
    X <- matrix(rnorm(10 * n), n, 10) 
    y <- drop(X %*% runif(10)) + rnorm(n) 
    Z <- cbind(y, X) 
    
    # assign other function 
    dolm <- function(x) 
        coef(lm.fit(x[, -1], x[, 1])) 
    
    # show that they yield the same 
    library(zoo) 
    all.equal(
        rollapply(Z, wdth, FUN = dolm, 
          by.column = FALSE, align = "right", fill = NA_real_), 
        roll_coef(X, y, wdth), 
        check.attributes = FALSE) 
    #R> [1] TRUE 
    
    # benchmark 
    library(compiler) 
    roll_coef <- cmpfun(roll_coef) 
    dolm <- cmpfun(dolm) 
    microbenchmark::microbenchmark(
        new = roll_coef(X, y, wdth), 
        prev = rollapply(Z, wdth, FUN = dolm, 
            by.column = FALSE, align = "right", fill = NA_real_), 
        times = 10) 
    #R> Unit: milliseconds 
    #R> expr  min   lq  mean  median   uq  max neval cld 
    #R> new 8.631319 9.010579 9.808525 9.659665 9.973741 11.87083 10 a 
    #R> prev 118.257128 121.734860 124.489826 122.882318 127.195410 135.21280 10 b 
    

    をあなたはC言語でそれをすることによって、これをスピードアップすることができ++ができますが、(Rを更新するか、別の関数)LINPACKからdchuddchddサブルーチンが必要になりますより

    が、これは roll_coefへのコールの前に3回のコール( model.frameに1回追加)です。

    関連する問題