按组滚动回归 [英] Rolling Regression by Group

查看:30
本文介绍了按组滚动回归的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

嗨,我有一个面板数据集。我想对每家公司进行滚动窗口回归,并提取独立变量的系数。y是因变量,x是独立变量。滚动窗口是12。也就是说, 第一回归使用行1到行12的数据, 第二次回归使用第2行到第13行数据,依此类推。 使用了RollApply。

下面是一个与我遇到的错误完全相同的问题: Rolling by group in data.table R 这个问题幸运的是,它只需要一个专栏,而我的问题需要两个专栏进行回归,所以我不能根据那篇帖子中的推荐答案进行相应的更改。 这里是另一个使用for循环的POST。我的真实数据有200多万个观测值,所以速度太慢了: rolling regression with 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"的列,显示变量x的系数。因此,对于每家公司,第一个数据应该从第12次观察开始生效。

看起来回归是从第1行取不同组的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

这篇关于按组滚动回归的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆