使用 Rollapply return 系数和 R 方

Using Rollapply to return both the Coefficient and RSquare

我有一个看起来像这样的数据集:

data.table(x=c(11:30),y=rnorm(20))

我想计算最近 10 项的滚动回归系数和 rsquared:

dtset[,coefficient:=rollapply(1:20,width=10,FUN=function(a) {
  subdtset <- dtset[a]
  reg <- lm.fit(matrix(data=c(subdtset$x, rep(1,nrow(subdtset))), nrow=nrow(subdtset), ncol=2), subdtset$y)
  return(coef(reg)[1])
},align="right",fill=NA)]
dtset[,rsquare:=rollapply(1:20,width=10,FUN=function(a) {
  subdtset <- dtset[a]
  reg <- lm.fit(matrix(data=c(subdtset$x, rep(1,nrow(subdtset))), nrow=nrow(subdtset), ncol=2), subdtset$y)
  return(1 - sum((subdtset$y - reg$fitted.values)^2) / sum((subdtset$y - mean(subdtset$y, na.rm=TRUE))^2))
},align="right",fill=NA)]

上面的代码完成了这个,但是我的数据集有数百万行,我有多个列,我想在其中进行这些计算,所以需要很长时间。我希望有一种方法可以加快速度:

  1. 有没有更好的方法来捕获 rollapply 中的最后 10 个项目,而不是将行号作为变量 a 传递,然后执行 subdtset <- dtset[a]?我尝试使用 .SD 和 .SDcols 但无法正常工作。我只能弄清楚如何让 rollapply 接受一列或向量作为输入,而不是两个 columns/vectors.
  2. 有没有办法从一个 rollapply 语句中 return 2 个值?我认为,如果我只需要进行一次回归,然后从中获取系数并计算 R 方,我就可以节省大量时间。做两次相同的计算效率很低。

感谢您的帮助!

使用 by.column = FALSE 将两列都传递给函数。在函数中直接计算斜率和r平方,避免lm.fit的开销。请注意,rollapply 可以 return 一个向量,并且 rollapplyr 的末尾带有 r 是右对齐的。如果 dtset 由单个 x 列后跟多个 y 列组成,这也适用,如下例中的内置 anscombe 数据框。

library(data.table)
library(zoo)

stats <- function(X, x = X[, 1], y = X[, -1]) {
  c(slope = cov(x, y) / var(x), rsq = cor(x, y)^2)
}
rollapplyr(dtset, 10, stats, by.column = FALSE, fill = NA)

a <- anscombe[c("x3", "y1", "y2", "y3")]
rollapplyr(a, 3, stats, by.column = FALSE, fill = NA)

检查

我们使用内置的 BOD 数据框检查公式。

fm <- lm(demand ~ Time, BOD)
c(coef(fm)[[2]], summary(fm)$r.squared)
## [1] 1.7214286 0.6449202

stats(BOD)
##     slope       rsq 
## 1.7214286 0.6449202