【问题标题】:rolling regression of each window with groupby使用 groupby 对每个窗口进行滚动回归
【发布时间】:2020-10-08 15:20:03
【问题描述】:

我有每个组的月度数据,我想对每个组做回归,窗口是 2 年并得到斜率。

我尝试了几种方法

  1. 我尝试使用 for 循环,每次过滤 2 年的数据,然后执行 lm
df$Year =year(df$date)
df1<-purrr::map_df(min(df$Year):(max(df$Year) - 2), function(i) {
             df %>%
              filter(Year%in% c(i,i+1)) %>%
              group_by(group)%>%
    do(lm = lm(R ~ M, data = .,na.action=na.exclude)) %>%
      mutate(lm_b0 = summary(lm)$coeff[1],
             lm_b1 = summary(lm)$coeff[2])%>%
    ungroup()
  })

得到错误:

lm.fit 中的错误(x,y,偏移量 = 偏移量,奇异值.ok = 奇异值.ok,...) : 0 (non-NA) 案例

  1. 然后我试图定义一个函数斜率,但结果df1,列“斜率”都是NA
slope <- . %>% { cov(.[, 2], .[, 1]) / var(.[, 2])}
df1<-df %>%
       group_by(group,Year) %>%
       mutate(slope = rollapplyr(cbind(R, M), 2, slope, by.column = FALSE, fill = NA)) %>%ungroup()
  1. 我找到了 roll_lm 方法:
library(roll)
df1<-df%>%
  group_by(group,Year)%>%
  roll_lm(MKT,RET,2)

得到错误:

roll_lm(., M, R, 5) 中的错误:找不到对象“M”

4.我试过这个,但结果都是NA

df1<-df%>%
  group_by(group,Year)%>%
  do(data.frame(., rolling_coef = rollapplyr(data = ., width = 2, FUN = function(df_) {
    mod = lm(R ~ M, data = .)
    return(coef(mod)[2])
  }, by.column = FALSE, fill = NA)))

我也试过直接使用beta,它可以工作,但似乎beta是非负数值变量,我的M和R有负值。

有人能给我一些想法吗?谢谢!

我的数据集与此类似:

我希望结果是:(2002 年:使用前两年的月度数据进行回归并找到斜率)

【问题讨论】:

  • 请提供一个代表
  • 对不起。我以前没有使用过reprex。而且总是出错。我在 github 中做了一个示例代码和数据文件。 github.com/lingqi-w/testing.git
  • @ling 他们的意思是一个最小的可重现示例,请参阅:stackoverflow.com/a/5963610/6574038
  • set.seed(1) Data &lt;- data.frame( group = sample(letters[1:4], 500, replace = TRUE), date= sample(seq(as.Date('2000/01/01'), as.Date('2003/01/01'),by="m"), 500, replace = TRUE), R=sample(runif(20),500,replace = TRUE), M=sample(runif(10),500,replace = TRUE) ) 谢谢@jay.sf 真的很有帮助。我创建了一个示例数据集。

标签: r


【解决方案1】:

也许你想要这个。

res <- do.call(rbind, lapply(0:6, function(y) 
  do.call(rbind, by(d, d$g, function(g) {
    b <- unname(lm(R ~ M, g[substr(g$t, 1, 4) %in% (2000:2001 + y), ])$coe)
    data.frame(group=g$g[[1]], date=2002 + y, b0=b[1], b1=b[2])
  }))
  ))
res
#    group date          b0          b1
# a      a 2002  0.11269711  0.50982041
# b      b 2002 -0.18383806  0.77395640
# a1     a 2003 -0.04830032  0.38158442
# b1     b 2003  0.05165555 -0.02668866
# a2     a 2004  0.04793637 -0.15872739
# b2     b 2004  0.27075037 -0.28167401
# a3     a 2005 -0.17276432 -0.41435303
# b3     b 2005  0.21656421 -0.22557376
# a4     a 2006 -0.29442007  0.45387752
# b4     b 2006 -0.02507721 -0.09527979
# a5     a 2007 -0.11417319  0.54403146
# b5     b 2007 -0.34265074 -0.33346084
# a6     a 2008 -0.13838241  0.33467995
# b6     b 2008 -0.02713155  0.25299279

数据:

set.seed(42)
d <- expand.grid(g=letters[1:2], t=seq(as.Date("2000-01-01"), length.out=96, by="m"),
                 stringsAsFactors=F)
d <- transform(d, R=round(rnorm(nrow(d)), 2), M=round(rnorm(nrow(d))/2, 2))

【讨论】:

  • 感谢您的回复。我试图获取数据,并得到错误:Error in stringsAsFactors &amp;&amp; is.character(x) : invalid 'x' type in 'x &amp;&amp; y'. 所以我尝试在我的数据集中应用此方法:使用res &lt;- do.call(rbind, lapply(0:6, function(y) do.call(rbind, by(df, df$group, function(group) { b &lt;- unname(lm(R ~ M, group[substr(group$Year, 1, 4) %in% (2000:2001 + y), ])$coe) data.frame(group=group$group[[1]], date=2002 + y, b0=b[1], b1=b[2]) })) )) 我想我误解了代码的结构?
  • @ling 你把Year放在哪里,你应该把整个日期,例如2000/1/1。可能你会得到我的一些数据作为因素。您正在运行哪个 R 版本(输入 version)?
  • 我的版本是4.0.2(2020-06-22),Mac。哦,我明白了,stringAsFactors 可以替换为replace = TRUE。然后它可以运行
猜你喜欢
  • 2015-04-03
  • 1970-01-01
  • 1970-01-01
  • 2020-08-25
  • 2021-08-20
  • 1970-01-01
  • 1970-01-01
  • 2017-11-29
  • 2017-09-16
相关资源
最近更新 更多