我要简化我的问题,以证明我不只是把你的任务交给你们。我真的想学习如何使循环与回归一起工作。
假设我想运行两个OLS但我不想两次输入相同的ols命令或者在我的脚本中添加另一系列命令。这是因为a)我实际上有两个以上的回归和b)我想尽可能高效地编写这个代码(我已经尝试过复制和粘贴相同的ols命令)。另外,我不只是运行一个简单的OLS,因为我还运行HAC估计器,具体取决于序列相关性和异方差性测试。
到目前为止我提出的代码是,
包
if (!require("lmtest")) install.packages("lmtest")
library("lmtest")
if (!require("sandwich")) install.packages("sandwich")
library("sandwich")
数据
data<-read.csv(file.choose())
x1<-data$x1
x2<-data$x2
x3<-data$x4
x5<-data$x5
x6<-data$x6
x7<-data$x7
y1<-data$y1
回归
reg1<-(y1 ~ x1 + x2 + x3 + x4)
reg2<-(y1 ~ x2 + x4 + x6 + x7)
p<-0.05
循环
for (i in 1:2) {
#OLS#
ols[i]<-lm(reg[i])
#Breusch-Pagan Test#
bptest(ols[i],varformula = NULL, studentize = TRUE)
bpp<-bptest(ols[i])$p.value
if(bpp>p) hs<-F else hs<-T
#Breusch-Godfrey Serial Correlation Test#
bgtest(ols[i],order=2,order.by=NULL,type=c("Chisq"))
bgp<-bgtest(ols[i])$p.value
if(bgp>p) sc<-F else sc<-T
#HAC Estimator#
HAC<-vcovHAC(ols[i],order.by=NULL,prewhite=FALSE,adjust=TRUE,diagnostics=FALSE,sandwich = TRUE,ar.method = "ols")
if (sc==T|hs==T) coeftest(ols[i],vcov.=HAC) else ols[i]
if (sc==T|hs==T) write.csv(coeftest(ols[i],vcov.=HAC),file="ols[i]HAC.csv") else write.csv(summary(ols[i])$coefficient,file="ols1.csv")
}
当我跑步时,我得到了
Error in stats::model.frame(formula = reg[i], drop.unused.levels = TRUE) : object 'reg' not found
我也用
尝试了上面的代码for (i in reg[1]:reg[2]) {
}
但它只返回
Error: object 'reg' not found.
我哪里出错了?
答案 0 :(得分:2)
这对于评论来说太长了,所以我将其作为部分答案发布。
差异似乎是公式,您要求一种方法来提高您的代码效率。一种方法是使用list
公式,然后将列表与lapply
结合使用。例如,
reg <- list(
reg1 = as.formula(y1 ~ x1 + x2 + x3 + x4),
reg2 = as.formula(y1 ~ x2 + x4 + x6 + x7)
)
ols <- lapply(reg, function(x) lm(x, data=data))
这里,ols
是两个元素的列表,每个元素都是对应于公式列表的回归。您可以对其他函数使用相同的原则,例如:
bgtests <- lapply(ols, function(x)
bgtest(x,order=2,order.by=NULL,type=c("Chisq")))
这将为bgtest
中存储的每个回归执行ols
函数。以类似的方式,你可以编写它,以便它执行你的异方差校正等。重点是:你提供list
到lapply
,该列表的每个元素都是通过的到您提供的功能。然后,lapply
的输出为list
,其输出为该函数。
如果您不想使用lapply
并解决实际问题:代码中的问题是没有名为reg
的对象。因此,设置不存在的对象(例如reg[1]
)不起作用。如果您执行上面代码的第一行,reg[1]
和reg[2]
将被定义,以便您的循环可以正常工作。
答案 1 :(得分:1)
'get'功能是你想要的,与'paste'结合使用。下面我使用R中的汽车数据拟合两个回归。然后我想写一个提取其系数的循环。 'get'函数会找到与您指定的对象名匹配的对象。
> (reg1 <- lm(dist ~ speed, data = cars))
Call:
lm(formula = dist ~ speed, data = cars)
Coefficients:
(Intercept) speed
-17.579 3.932
> (reg2 <- lm(dist ~ 1 + I(speed^2), data = cars))
Call:
lm(formula = dist ~ 1 + I(speed^2), data = cars)
Coefficients:
(Intercept) I(speed^2)
8.860 0.129
> coeff <- matrix(0, nrow = 2, ncol = 2)
> for (i in 1:2)
+ {
+
+ # Main step
+ model <- get(paste("reg", i, sep = ""))
+ coeff[i,] <- coefficients(model)
+ }
> coeff
[,1] [,2]
[1,] -17.579095 3.9324088
[2,] 8.860049 0.1289687
>