2012-07-20 24 views
1

我試圖獲得R中動態時間序列的滾動預測(然後計算預測的平方誤差)。我基於this StackOverflow question上的很多代碼,但我對R非常陌生,所以我掙扎了很多。任何幫助將非常感激。動態時間序列預測和滾動

require(zoo) 
require(dynlm) 

set.seed(12345) 
#create variables 
x<-rnorm(mean=3,sd=2,100) 
y<-rep(NA,100) 
y[1]<-x[1] 
for(i in 2:100) y[i]=1+x[i-1]+0.5*y[i-1]+rnorm(1,0,0.5) 
int<-1:100 
dummydata<-data.frame(int=int,x=x,y=y) 

zoodata<-as.zoo(dummydata) 

prediction<-function(series) 
    { 
    mod<-dynlm(formula = y ~ L(y) + L(x), data = series) #get model 
    nextOb<-nrow(series)+1 
    #make forecast 
    predicted<-coef(mod)[1]+coef(mod)[2]*zoodata$y[nextOb-1]+coef(mod)[3]*zoodata$x[nextOb-1] 

    #strip timeseries information 
    attributes(predicted)<-NULL 

    return(predicted) 
    }     

rolling<-rollapply(zoodata,width=40,FUN=prediction,by.column=FALSE) 

這將返回:

20   21  .....  80 
10.18676 10.18676   10.18676 

裏面有兩個問題,我沒想到:從20-> 80,不40-> 100我希望

  1. 奔跑(如寬度爲40)
  2. 它給出的預測值是常數:10.18676

我在做什麼錯?有沒有更容易的方法來做預測,而不是全部寫出來?謝謝!

回答

2

你的功能的主要問題是data參數dynlm。如果您查看?dynlm,您會看到參數data必須是data.framezoo對象。不幸的是,我剛剛瞭解到rollapply會將您的zoo對象拆分爲array對象。這意味着dynlm在注意到您的data參數不正確之後,在您的全球環境中搜索了xy,這些環境當然是在您的代碼頂部定義的。解決方案是將series轉換爲zoo對象。有一對夫婦與你的代碼的其他問題,我在這裏發佈修正版本:

prediction<-function(series) { 
    mod <- dynlm(formula = y ~ L(y) + L(x), data = as.zoo(series)) # get model 
    # nextOb <- nrow(series)+1 # This will always be 21. I think you mean: 
    nextOb <- max(series[,'int'])+1 # To get the first row that follows the window 
    if (nextOb<=nrow(zoodata)) { # You won't predict the last one 
    # make forecast 
    # predicted<-coef(mod)[1]+coef(mod)[2]*zoodata$y[nextOb-1]+coef(mod)[3]*zoodata$x[nextOb-1] 
    # That would work, but there is a very nice function called predict 
    predicted=predict(mod,newdata=data.frame(x=zoodata[nextOb,'x'],y=zoodata[nextOb,'y'])) 
    # I'm not sure why you used nextOb-1 
    attributes(predicted)<-NULL 
    # I added the square error as well as the prediction. 
    c(predicted=predicted,square.res=(predicted-zoodata[nextOb,'y'])^2) 
    } 
}  

rollapply(zoodata,width=20,FUN=prediction,by.column=F,align='right') 

你的第二個問題,關於你的結果的編號,可以通過align參數進行控制是rollapplyleft會給你1..60,center(默認)會給你20..80right得到你40..100

+0

非常感謝!完美的作品! – MatthewK 2012-07-21 02:56:05