使用 NA 对多个列进行滚动回归

Rolling Regression over several columns with NA´s

我正在尝试 运行 多重滚动-window 回归并为每个回归保存 beta。 我的数据集 (df) 非常大(577 行;15000 列),看起来如下所示:

         date  Inflation  RET.1  RET.2  RET.3  RET.4  RET.5          
    1    2020    1.22      0.28  -0.21    NA   0.11   0.01
    2    2019    1.12      0.11  -0.11    NA   0.03   0.21    
    3    2018    1.52      0.24  -0.71    NA   0.91   0.01    
    4    2017    1.26      0.38  -0.41  -0.21   NA    0.21
    5    2016    0.22      0.74  -0.28   0.61   NA    0.07
    6    2015    1.62       NA     NA   -0.12  0.47   0.41
    7    2014    1.28       NA     NA    0.34  0.31   0.12
    8    2013    1.21       NA     NA   -0.56  -0.1   0.25

在我给出的示例中,我想在 Inflation 上通过 RET.5 回归列 RET.1 (lm(RET.1 ~ Inflation);lm(RET.2 ~ Inflation)...) 用于前 3 个观察。然后保存 beta(斜率系数)。然后 运行 在下一个 3(所以第 2 行到第 4 行)并保存下一个测试版。我想为不同的 RET 值执行此操作 5 次,并且只有在三个观察值中没有缺失值时才应执行回归,否则 return NA.

因此我想得到的是以下几行:

Date  RET.1  RET.2  RET.3  RET.4  RET.5
2020  coef   coef   NA     coef   coef
2019  coef   coef   NA      NA    coef
2018  coef   coef   NA      NA    coef
2017   NA    NA    coef     NA    coef
2016   NA    NA    coef     NA    coef

我想在 RET.1-5 列上循环 roll_regres 函数(@Benjamin Christoffersen:thx 用于创建这个很棒的函数!)。作为测试,我首先使用以下代码将 roll_regress 函数仅应用于 RET.1 列:

betas <- roll_regres(RET.1 ~ Inflation, df, width = 3, do_downdates=TRUE, min_obs = 3)

这可是 returns:

Error in na.fail.default(list(RET.1 = c(0.28, 0.11,  : 
  missing values in object

似乎默认的 roll_regres 函数在处理 NA 时存在问题。 有没有人有关于如何执行带有缺失值的 roll_regres 函数然后循环它的解决方案? 或者这可能不是正确的方法,有更好的方法吗?

已经非常感谢了。祝一切顺利

玫瑰

使用最后注释中的数据以及 cov(x, y) / var(x) 给出回归 y 对 x 的斜率这一事实。如果 y 是一个数据框,它会给出每列的斜率。斜率函数的主体与 coef(lm(as.matrix(Y) ~ x, subset = ix))[2, ] 类似,但以所需方式处理 NA。

library(zoo)

w <- 3
nms <- startsWith(names(DF), "RET")
slopes <- function(ix, x, Y) cov(x = x[ix], y = Y[ix,]) / var(x[ix])
betas <- rollapply(1:nrow(DF), w, slopes, align = "left", 
  x = DF$Inflation, Y = DF[nm])
replace(head(DF, -(w-1)), nms, betas)  # combine DF and betas

给予:

  date Inflation      RET.1     RET.2      RET.3    RET.4        RET.5
1 2020      1.22  0.2192308 -1.538462         NA 2.307692 -0.384615385
2 2019      1.12  0.2160194 -1.456311         NA       NA -0.533980583
3 2018      1.52 -0.3736264 -0.271978         NA       NA  0.005494505
4 2017      1.26         NA        NA -0.5809788       NA  0.218718466
5 2016      0.22         NA        NA -0.4578020       NA  0.196174044
6 2015      1.62         NA        NA  0.3014553 1.097713  0.537422037

我们仔细检查输出的 RET.2 列中的第一个值:

coef(lm(RET.2 ~ Inflation, DF, subset = 1:3))[[2]] 
## [1] -1.538462

备注

DF <- structure(list(date = 2020:2013, Inflation = c(1.22, 1.12, 1.52, 
1.26, 0.22, 1.62, 1.28, 1.21), RET.1 = c(0.28, 0.11, 0.24, 0.38, 
0.74, NA, NA, NA), RET.2 = c(-0.21, -0.11, -0.71, -0.41, -0.28, 
NA, NA, NA), RET.3 = c(NA, NA, NA, -0.21, 0.61, -0.12, 0.34, 
-0.56), RET.4 = c(0.11, 0.03, 0.91, NA, NA, 0.47, 0.31, -0.1), 
    RET.5 = c(0.01, 0.21, 0.01, 0.21, 0.07, 0.41, 0.12, 0.25)), 
class = "data.frame", row.names = c("1", 
"2", "3", "4", "5", "6", "7", "8"))