【问题标题】:Problems with rollapply in regression equation回归方程中的rollapply问题
【发布时间】:2020-01-28 16:23:42
【问题描述】:

我正在处理每日股票数据,我正在尝试根据 t-11 个月时间窗口的每日股票数据计算第 t 月的每月 beta 值(例如,12 月的 beta 包含从 1 月到 12 月的每日股票数据) )。此外,我想在回归方程中包含至少 150 个观察值。 ->Link to data screenshot

我想通过计算过去 12 个月的超额股票收益对超额市场收益的回归系数来计算 beta。我的样本数据在最后一列列出了每只股票的超额收益(股票按数字分类)和市场收益 mktrf。

我想出了以下代码,但不幸的是我找不到错误:我在过去 12 个月中使用了 width=252 的天数,但尚未在代码中包含至少 150 次观察的先决条件。当股票退市时,我也遇到了 NA 的麻烦。我搜索了论坛,我只能找到与答案中相同的代码,所以我不知道我做错了什么。

rollingbeta <- rollapply(joined_data,
                     width=252,
                     FUN = function(x) {
                       t = lm(formula=paste0(" ` ", x , " ` ~ mktrf"), data = x, na.rm=T);
                       return(t$coef) },
                     by.column=TRUE, 
                      align="right")

理想情况下,我希望以与输入表相同的数据格式查找输出。

对此有什么想法吗?非常感谢任何帮助!

这是一个使用 dput 创建的示例:

结构(列表(日期 = 结构(c(16804、16805、16806、16807、 16808, 16811, 16812, 16813, 16814, 16815), class= "日期"), 10001 = c(NA, -0.0132978723404255, 0.0148247978436657, 0.0146082337317397, 0.0196335078534031, 0.0346598202824133, 0.0235732009925558, 0, -0.0145454545454544, -0.0172201722017221), 93436 = c(NA, 8.95215075422673e-05, -0.0196482119679542,-0.0154766252739225,-0.0215627173661025, -0.0149289099526067,0.0101996632186674,-0.0460065723674811, 0.0293045779042485, -0.00577165583470751), mktrf = c(-0.0159, 0.0012, -0.0135, -0.0244, -0.0111, -6e-04, 0.0071, -0.0267, 0.0165, -0.0214)), row.names = c(NA, 10L), class= "data.frame")

【问题讨论】:

  • 对此@G.Grothendieck 感到抱歉。我只是想确保为这么大的滚动窗口包含足够的观察结果。我更新了较小版本的 dput 输出,希望现在可以使用!
  • data.table 对象不适用于dput,因为它们包含不可重现的内部指针。请先转换成数据框。
  • 很抱歉,没有意识到这一点!我现在改了。

标签: r dplyr lm rollapply


【解决方案1】:

我无法读取您的数据,但使用 BOD(R 附带)我们使用 5 行窗口执行滚动回归,或者如果 5 行不可用,则使用至少提供 3 的可用行数行可用。我们还检查至少有 3 个完整的案例。

我们通过使用宽度向量而不是单个宽度来完成上述操作。这个向量表示要使用多少行。如果至少有 5 行可用,我们使用 5,否则使用可用的行数;但是,如果可用的行数少于 3,那么我们使用 3,这将导致为该行生成 NA。

coefs 内,我们还会检查是否有少于 3 个完整案例,如果是则返回 NA。

library(zoo)

n <- nrow(BOD)  # 6
w <- pmax(pmin(1:n, 5), 3)  # 3 3 3 4 5 5

coefs <- function(x) {
  if (sum(complete.cases(x)) >= 3) coef(lm(as.data.frame(x))) else c(NA, NA)
}
rollapplyr(BOD[2:1], w, coefs, by.column = FALSE, fill = NA)

给予:

     (Intercept)     Time
[1,]          NA       NA
[2,]          NA       NA
[3,]    1.833333 5.350000
[4,]    5.450000 3.180000
[5,]    7.750000 2.030000
[6,]   10.674324 1.301351

这给出了相同的结果:

rbind(c(NA, NA), 
      c(NA, NA), 
      coefs(BOD[1:3, 2:1]), 
      coefs(BOD[1:4, 2:1]), 
      coefs(BOD[1:5, 2:1]), 
      coefs(BOD[2:6, 2:1]))

更新

添加的较短的 dput 输出给出了语法错误,但这次它足够短,我能够将它编辑(见最后的注释)成有效的东西。

我们使用 8 的宽度,或者如果可用的宽度少于 8,我们至少使用 4,否则我们返回 NA。如果coefs,我们也至少使用 3 个完整的案例。

我们将 DF 转换为 zoo 对象,并假设最后(第 3 列)是因变量,其他 2 列是自变量。

library(zoo)

n <- nrow(DF)  # 10
w <- pmax(pmin(1:n, 8), 4)  #  [1] 4 4 4 4 5 6 7 8 8 8


coefs <- function(x) {
  if (sum(complete.cases(x)) >= 3) coef(lm(as.data.frame(x))) else c(NA, NA)
}

z <- read.zoo(DF)[, c(3, 1, 2)]
rollapplyr(z, w, coefs, by.column = FALSE, fill = NA)

给这个动物园对象:

            (Intercept)     `10001`    `93436`
2016-01-04           NA          NA         NA
2016-01-05           NA          NA         NA
2016-01-06           NA          NA         NA
2016-01-07 -0.031077046 -2.44567879 -2.7398798
2016-01-08 -0.034601587 -2.65028219 -3.2757924
2016-01-11  0.003069533  0.35951677  1.2452355
2016-01-12 -0.001737647  0.15052197  0.7341502
2016-01-13 -0.001773568  0.09143210  0.5979455
2016-01-14 -0.001173643  0.07543222  0.6164919
2016-01-15 -0.005337689  0.28461054  0.6305395

注意

DF <- structure(list(date = structure(c(16804, 16805, 16806, 16807, 
16808, 16811, 16812, 16813, 16814, 16815), class = "Date"), `10001` = c(NA, 
-0.0132978723404255, 0.0148247978436657, 0.0146082337317397, 
0.0196335078534031, 0.0346598202824133, 0.0235732009925558, 0, 
-0.0145454545454544, -0.0172201722017221), `93436` = c(NA, 8.95215075422673e-05, 
-0.0196482119679542, -0.0154766252739225, -0.0215627173661025, 
-0.0149289099526067, 0.0101996632186674, -0.0460065723674811, 
0.0293045779042485, -0.00577165583470751), mktrf = c(-0.0159, 
0.0012, -0.0135, -0.0244, -0.0111, -6e-04, 0.0071, -0.0267, 0.0165, 
-0.0214)), row.names = c(NA, 10L), class = "data.frame")

【讨论】:

  • 感谢您的帮助!我试图用我的数据复制你的代码,但我只收到 NA。我已经更新了我的示例数据,所以我希望它现在可以工作!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-14
  • 2019-02-06
  • 2016-05-10
  • 2011-08-09
  • 1970-01-01
相关资源
最近更新 更多