我需要将 lm()
应用于我的数据帧 dat
的扩大子集,同时对下一次观察进行预测。例如,我在做:
fit model predict
---------- -------
dat[1:3, ] dat[4, ]
dat[1:4, ] dat[5, ]
. .
. .
dat[-1, ] dat[nrow(dat), ]
我知道我应该为特定的子集做什么(与这个问题相关:predict() and newdata - How does this work?)。例如预测最后一行,我做
dat1 = dat[1:(nrow(dat)-1), ]
dat2 = dat[nrow(dat), ]
fit = lm(log(clicks) ~ log(v1) + log(v12), data=dat1)
predict.fit = predict(fit, newdata=dat2, se.fit=TRUE)
我如何为所有子集自动执行此操作,并可能将我想要的内容提取到表中?
- 从
fit
开始,我需要summary(fit)$adj.r.squared
; - 从
predict.fit
我需要predict.fit$fit
值。
谢谢。
最佳答案
(高效)解决方案
这是你可以做的:
p <- 3 ## number of parameters in lm()
n <- nrow(dat) - 1
## a function to return what you desire for subset dat[1:x, ]
bundle <- function(x) {
fit <- lm(log(clicks) ~ log(v1) + log(v12), data = dat, subset = 1:x, model = FALSE)
pred <- predict(fit, newdata = dat[x+1, ], se.fit = TRUE)
c(summary(fit)$adj.r.squared, pred$fit, pred$se.fit)
}
## rolling regression / prediction
result <- t(sapply(p:n, bundle))
colnames(result) <- c("adj.r2", "prediction", "se")
请注意,我在 bundle
函数中做了几件事:
- 我已使用
subset
参数来选择适合的子集 - 我已使用
model = FALSE
不保存模型框架,因此我们保存了工作区
总体来说没有明显的循环,但是使用了sapply
- 拟合从
p
开始,即用p
系数拟合模型所需的最少数据数; - 拟合终止于
nrow(dat) - 1
,因为我们至少需要最后一列进行预测。
测试
示例数据(包含 30 个“观察值”)
dat <- data.frame(clicks = runif(30, 1, 100), v1 = runif(30, 1, 100),
v12 = runif(30, 1, 100))
应用上面的代码给出了结果
(总共 27 行,截断了 5 行的输出)
adj.r2 prediction se
[1,] NaN 3.881068 NaN
[2,] 0.106592619 3.676821 0.7517040
[3,] 0.545993989 3.892931 0.2758347
[4,] 0.622612495 3.766101 0.1508270
[5,] 0.180462206 3.996344 0.2059014
第一列是拟合模型的调整 R.squared 值,第二列是预测值。 adj.r2
的第一个值是 NaN
,因为我们拟合的第一个模型有 3 个系数对应 3 个数据点,因此没有可用的合理统计数据。 se
也会发生同样的情况,因为拟合线没有 0 残差,所以预测是在没有不确定性的情况下完成的。
关于使用 lm() 和 predict() 进行滚动回归和预测,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38041167/