问题描述
某些预先编程的模型会自动在lm()
的回归输出(例如R
)中删除线性因变量。对于bife
包,这似乎是不可能的。如第5页的CRAN中的软件包说明中所述:
现在,假设当前的问题涉及进行许多回归,并且一个人不能充分检查每个回归输出-人们必须假设关于回归变量的某种经验法则。或多或少地自动删除线性相关回归变量并获得适当模型规格的替代方案是什么?
我将代码设置为以下示例:
#sample coding
x=10*rnorm(40)
z=100*rnorm(40)
df1=data.frame(a=rep(c(0,1),times=20),x=x,y=x,z=z,ID=c(1:40),date=1,Region=rep(c(1,2,3,4),10))
df2=data.frame(a=c(rep(c(1,0),times=15),rep(c(0,times=5)),x=1.4*x+4,y=1.4*x+4,z=1.2*z+5,date=2,10))
df3=rbind(df1,df2)
df3=rbind(df1,df2)
for(i in 1:4) {
x=df3[df3$Region==i,]
model = bife::bife(a ~ x + y + z | ID,data = x)
results=data.frame(Region=unique(df3$Region))
results$Model = results
if (i==1){
df4=df
next
}
df4=rbind(df4,df)
}
Error: Linear dependent terms detected!
解决方法
由于您仅查看线性相关性,因此可以简单地利用检测到它们的方法,例如lm
。
以下是使用fixest
软件包的解决方案示例:
library(bife)
library(fixest)
x = 10*rnorm(40)
z = 100*rnorm(40)
df1 = data.frame(a=rep(c(0,1),times=20),x=x,y=x,z=z,ID=c(1:40),date=1,Region=rep(c(1,2,3,4),10))
df2 = data.frame(a=c(rep(c(1,0),times=15),rep(c(0,times=5)),x=1.4*x+4,y=1.4*x+4,z=1.2*z+5,date=2,10))
df3 = rbind(df1,df2)
vars = c("x","y","z")
res_all = list()
for(i in 1:4) {
x = df3[df3$Region == i,]
coll_vars = feols(a ~ x + y + z | ID,x,notes = FALSE)$collin.var
new_fml = xpd(a ~ ..vars | ID,..vars = setdiff(vars,coll_vars))
res_all[[i]] = bife::bife(new_fml,data = x)
}
# Display all results
for(i in 1:4) {
cat("\n#\n# Region: ",i,"\n#\n\n")
print(summary(res_all[[i]]))
}
此处所需的功能是feols
和xpd
,两者来自fixest
。一些解释:
-
feols
与lm
一样,当发现它们是共线的时,会即时删除它们。它将共线变量的名称存储在插槽$collin.var
中(如果找不到,则为NULL
)。 -
与
lm
相反,feols
也允许固定效果,因此您在查找线性依赖项时可以将其添加:这样一来,您可以发现复杂的线性依赖项,其中还涉及到固定效果。 -
我设置了
notes = FALSE
,否则feols
会提示有关共线性的注释。 -
feols
速度快(对于大型数据集,其速度实际上比lm
快),因此不会对您的分析造成压力。 -
函数
xpd
扩展公式并用用户提供的关联参数替换以两个点开头的任何变量名。-
当
xpd
的参数为向量时,其行为是用加号将其强制。因此,如果提供了..vars = c("x","y")
,则公式a ~ ..vars | ID
将变为{{1} }。 -
此处将公式中的
a ~ x + y | ID
替换为..vars
,setdiff(vars,coll_vars))
是未发现共线变量的向量。
-
因此,您可以在执行bife
估算之前获得一种具有自动变量删除功能的算法。
最后,只是附带说明:一般来说,最好将结果存储在列表中,因为它避免了复制。
更新
我忘记了,但是如果您不需要偏差校正(bife::bias_corr
),则可以直接使用fixest::feglm
来自动删除共线变量:
res_bife = bife::bife(a ~ x + z | ID,data = df3)
res_feglm = fixest::feglm(a ~ x + y + z | ID,df3,family = binomial)
rbind(coef(res_bife),coef(res_feglm))
#> x z
#> [1,] -0.02221848 0.03045968
#> [2,] -0.02221871 0.03045990