写
在前面
“
对于任意一天t,在[t - n, t]的区间内进行回归。如果数据一共有N天,那么就会得到N - n个数据点
这就是滚动回归,一个非常容易理解而且在研究中常常遇见,然而实现起来却不是那么容易的问题。在今天的大猫课堂中,大猫教大家用10行代码搞定它!
PS:由于微信的限制,给大猫留言的小伙伴超过48小时后大猫就不能回复你们了。所以如果想联系大猫,可以按照文章最后的微信号加大猫微信哦。
问
题引入
假设我们现在有N天的数据,我们希望对于每一天t,用n作为窗口期,在[t - n, t]的窗口中进行数据回归。显然,最终的数据会有N-n天。
为此我们构造样例数据集,我们假设一共有5个不同的组,每组都由1000天的观测,包含自变量x与因变量y。此外,我们假设窗口期 n = 100 天。
图:样例数据集
构造样例数据集代码如下:
# 设置随机数种子
set.seed(42)
# 生成样例数据集,一共有a,b,c,d,e五个group,每个group都有1000日的观测
dt <- data.table(id = rep(letters[1:5], each = 1000), date = seq(as.Date("2001-01-01"), by = 'day', len = 1000 * 5), y = rnorm(1000 * 5), x = rnorm(1000 * 5)) %>% unique(by = c("id", "date"))
要实现一行代码完成分组回归,需要用到data.table包!
解
题思路
解决的思路并不复杂,假设我们现在要处理的是第t行,自变量和因变量分别是x和y,滚动窗口是n天,那么我们只要能够取到x[t-n, t]以及y[t-n,t]两个向量,把他放到lm函数中就可以进行回归得到结果。需要注意的是我们需要遍历每一个符合条件的t,以及需要把最终结果输出成一个漂亮的数据集。
步
骤分解
大猫先把代码放上来:
# 设定滚动窗口期,这里为100天
n <- 100
# 计算滚动回归!
re <- dt[, {
l <- list()
for (t in (n + 1) : .N) {
l[[t]] <- as.list(c(coef(lm(y ~ x, data = .SD[(t - n) : t])), date = date[t]))
}
rbindlist(l)
},
keyby = .(id)]
re[, ":="(date = as.Date(date, origin = "1970-01-01"))]
最终的输出数据集是这个样子的:
现在我们逐一分析这几行代码。
总
结
是不是很简单?其实要完成滚动回归并不止这一种方法,stackoverflow上有很多相关的帖子,但是大猫在比较几种方法之后,发现自己写的这个版本是代码最短、最容易理解、并且效率最高的!但是,这个滚动回归的代码也不是完美的,最大的劣势就在于我们的滚动窗口是用“期”而不是用“天”来定义的,也就是说,程序在每次滚动的时候都会固定找前面n期的观测,而不管这n期之间可能间隔的是10天,20天还是一个月。但是,对于大多数研究中,这种情况并不常见,所以大猫给出的代码还是能够应对大多数情况。