आर

2012-02-19 8 views
9

में एक एक्सटीएस श्रृंखला में रोलिंग विंडो रिग्रेशन को लागू करना मेरे पास 5 मुद्रा जोड़े के लिए 1033 दैनिक रिटर्न पॉइंट्स का एक एक्सटी है, जिस पर मैं रोलिंग विंडो रिग्रेशन चलाने के लिए चाहता हूं, लेकिन रोलप्ली मेरे परिभाषित फ़ंक्शन के लिए काम नहीं कर रहा है जो एलएम का उपयोग करता है()।आर

> 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 दिन खिड़की चलाना चाहते हैं:

> 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 

मैं आसानी से एक एल एम उस पर संपूर्ण डेटा सेट के लिए अन्य जोड़े के खिलाफ USDZAR मॉडल करने के लिए चला सकते हैं: यहाँ अपने डेटा है समय के साथ इन गुणांकों के विकास प्राप्त करने के लिए, तो मैं एक समारोह dolm जो ऐसा करता है बनाने के लिए:

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

लेकिन जब मैं इस पर rollapply चलाने मैं निम्नलिखित मिल:

> rollapply(fxr, 62, FUN = dolm) 
Error in terms.formula(formula, data = data) : 
    '.' in formula and no 'data' argument 

अपनी ही काम करता है पर ठीक भी dolm (FXR) यह है कि:

> 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 

किसी भी मदद की बहुत सराहना की। अनिवार्य रूप से मैं चाहता हूं कि 62Z दिन की खिड़की पर USDZAR ~ USDEUR + USDGBP + USDCHF + USDCAD के प्रतिगमन के लिए भार प्राप्त करना है।

उत्तर

9

वहाँ कई समस्याओं यहां हैं:

  • rollapply एक मैट्रिक्स से गुजरता है लेकिन lm एक data.frame की आवश्यकता है।
  • rollapply प्रत्येक कॉलम पर फ़ंक्शन को अलग से लागू करता है जब तक कि हम by.column=FALSE निर्दिष्ट करें।
  • आप या तिथियों के साथ गठबंधन सही होने के लिए परिणाम नहीं चाहते हो सकता है हो सकता है, लेकिन यदि आप rollapplyr प्रयोग करते हैं:

1) ऊपर शामिल हमने:

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

2) पर dolm में एक विकल्प lm.fit का उपयोग करना है जो सीधे मैट्रिस के साथ काम करता है और यह भी तेज़ है:

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

भयानक धन्यवाद। हां मैंने अभी भी बहुत खेल के बाद इसे बाहर काम किया। मुझे मूर्ख। by.column = निश्चित रूप से गलत! बहुत बहुत धन्यवाद। बस अपने चिड़ियाघर डॉक्टर बीटीडब्ल्यू पढ़ रहा था। उत्तम सामग्री। मुझे लगता है कि रोलप्ली थोड़ा उलझन में है कि एलएम() पूरे एक्सटीएस पर काम करता है, लेकिन यह इसके हिस्सों पर रोलप्ली() द्वारा लौटाया नहीं जाता है। एक उचित रूप से एक और xts वापस करने के लिए रोलप्ली की उम्मीद कर सकता है जो अभी भी एलएम() के तहत काम करेगा या क्या मुझे कुछ याद आ रहा है? मेला culpa by.column FALSE हालांकि। इसके लिए कोई बहाना नहीं है ... –

+0

क्या याद किया जाता है कि 'रोलप्ली' एक्सटी का हिस्सा नहीं है लेकिन यह चिड़ियाघर का हिस्सा है और इसके प्रेषण 'rollapply.zoo' है। –

+0

इसे स्पष्ट करने के लिए धन्यवाद। अभी तक: > fxr <- चिड़ियाघर (fxr) > कक्षा (fxr) [1] "चिड़ियाघर" > रोलप्ली (एफएक्सआर, 62, फ़ंक्शन (एक्स) कोफ (एलएम (यूएसडीजेएआर ~ एक्स, डेटा = एक्स)), by.column = FALSE) model.frame.default में त्रुटि (फॉर्मूला = USDZAR ~ x, डेटा = x, drop.unused.levels = TRUE): 'डेटा' डेटा.फ्रेम होना चाहिए, मैट्रिक्स या नहीं सरणी तो हमें अभी भी यह समस्या है। मैं समझता हूं ... आर के पास इस तरह के मुद्दे के आसपास बहुत कुछ है लेकिन अभी भी। हमारे यहां क्या है एलएम पूरी चिड़ियाघर वस्तु पर काम करता है लेकिन इसके रोलप्ले सबसेट पर काम नहीं करता है। –

1

एक तीसरा विकल्प नीचे दिए गए कोड में किए गए क्यूआर अपघटन में आर मैट्रिक्स को अपडेट करना होगा। आप सी में यह कार्य करके यह तेजी लाने के कर सकते हैं ++ लेकिन से आप Linpack से dchud और dchdd सबरूटीन्स (या आर अद्यतन करने के लिए एक और समारोह) की आवश्यकता होगी

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 

समाधान ऊपर आवश्यकता है कि आप फार्म model.matrix और model.response पहले लेकिन यह roll_coef पर कॉल से पहले केवल तीन कॉल (एक अतिरिक्त model.frame) है।