簡體   English   中英

分組滾動回歸

[英]Rolling Regression by Group

嗨,我有一個面板數據集。 我想對每個公司進行滾動窗口回歸,並提取獨立變量的系數。 y是因變量,x是因變量。 滾動窗口為12。也就是說,第一次回歸使用第1行到第12行數據,第二次回歸使用第2行到第13行數據,依此類推。使用Rollapply。

這是一個與我遇到的錯誤完全相同的問題: 在data.table R中按組滾動該問題的幸運之處在於,它僅占用一列,而我的需要兩列進行回歸,因此我無法進行更改根據該職位的建議答案。 這是另一個使用for循環的帖子。 我的真實數據有超過200萬個觀測值,所以實在太慢了: 使用dplyr進行滾動回歸有任何幫助嗎?

我的假數據集如下:

dt<-rep(c("AAA","BBB","CCC"),each=24)
dt<-as.data.frame(dt)
names(dt)[names(dt)=="dt"] <- "firm"
a<-c(20100131,20100228,20100331,20100430,20100531,20100630,20100731,20100831,20100930,20101031,20101130,20101231,20110131,20110228,20110331,20110430,20110531,20110630,20110731,20110831,20110930,20111031,20111130,20111231)
dt$time<-rep(a,3)
dt<-dt%>% group_by(firm)%>%
  mutate(y=rnorm(24,10,5))
dt<-dt%>% group_by(firm)%>%
  mutate(x=rnorm(24,5,2))
dt<-as.data.table(dt)

我嘗試了這段代碼:

# create rolling regression function
    roll <- function(Z) 
{ 
  t = lm(formula=y~x, data = as.data.frame(Z), na.rm=T); 
  return(t$coef[2]) 
}
dt[,beta := rollapply(dt, width=12, roll, fill=NA, by.column=FALSE, align="right") , by=firm]

我正在嘗試創建一個名為“ beta”的列,該列顯示var x的系數。 因此,對於每家公司,第一個數據應從第12個觀察中得出。

看來,回歸從第一行的x和y獲取了不同的組,並且與我從EXCEL得到的結果相比,系數似乎有些偏離。

我嘗試的第二種方法是dplyr版本:

dt %>%
group_by(firm) %>%
mutate(dt,beta = rollapply(dt,12,function(x) coef(lm(y~x,data=as.data.frame(x)))[2],by.column= FALSE, fill = NA, align = "right"))

它給了我同樣的問題。 每個組具有相同的編號。 看起來,對於每個公司,回歸都從第一行中獲取y和x。

有什么想法嗎? 非常感謝。

這是使用rollRegres包和data.table包的解決方案。 我還添加了OP解決方案的修改版本,該解決方案可以工作(請參閱eddi的評論),並使用了一個示例,其中包含200萬觀察值,OP提到

#####
# setup data
library(rollRegres)
library(data.table)
library(dplyr)

set.seed(33700919)
n_firms <- 83334 # yields ~ the 2M firm as the OP mentions
dt <- rep(1:n_firms, each = 24)
dt <- data.frame(firm = dt)
a <-c(20100131,20100228,20100331,20100430,20100531,20100630,20100731,20100831,20100930,20101031,20101130,20101231,20110131,20110228,20110331,20110430,20110531,20110630,20110731,20110831,20110930,20111031,20111130,20111231)
dt$time <- rep(a, n_firms)
dt <- dt %>% group_by(firm) %>% mutate(y=rnorm(24,10,5))
dt <- dt %>% group_by(firm) %>% mutate(x=rnorm(24,5,2))
dt <- as.data.table(dt)
nrow(dt) # roughly the 2M rows that the OP mentions
#R [1] 2000016

#####
# fit models
setkey(dt, firm, time) # make sure data is sorted correctly
start_time <- Sys.time() # to show computation time
dt[
  , beta :=
    roll_regres.fit(x = cbind(1, .SD[["x"]]), y = .SD[["y"]],
                    width = 12L)$coefs[, 2],
  by = firm]
Sys.time() - start_time
#R Time difference of 6.526595 secs

# gives the same as OP's solution with minor corrections
library(zoo)
start_time <- Sys.time()
roll <- function(Z)
  lm.fit(x = cbind(1, Z[, "x"]), y = Z[, "y"])$coef[2]
dt[
  , beta_zoo :=
    rollapply(.SD, width=12, roll, fill=NA, by.column=FALSE, align="right"),
  by=firm]
Sys.time() - start_time # much slower
#R Time difference of 1.87341 mins

# gives the same
all.equal(dt$beta, dt$beta_zoo)
#R [1] TRUE

也許您可以嘗試更改rollapply中的第一個參數,將dt替換為dt[, c("y","x")] 看看是否有效

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM