循环回归命令

时间:2016-03-23 11:24:24

标签: r

我要简化我的问题,以证明我不只是把你的任务交给你们。我真的想学习如何使循环与回归一起工作。

假设我想运行两个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. 

我哪里出错了?

2 个答案:

答案 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函数。以类似的方式,你可以编写它,以便它执行你的异方差校正等。重点是:你提供listlapply,该列表的每个元素都是通过的到您提供的功能。然后,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
>