我正在R中复制一个负二项式回归模型。在计算鲁棒标准误差时,输出与标准误差的Stata输出不匹配。
原始的Stata代码是
nbreg displaced eei lcostofwar cfughh roadskm lpopdensity ltkilled, robust nolog
我尝试了手动计算,也尝试了vcovHC
中的sandwich
。但是,两者都不会产生相同的结果。
我的回归模型如下:
mod1 <- glm.nb(displaced ~ eei + costofwar_log + cfughh + roadskm + popdensity_log + tkilled_log, data = mod1_df)
我使用vcovHC
尝试了从HC0
到HC5
的每个选项。
尝试1:
cov_m1 <- vcovHC(mod1, type = "HC0", sandwich = T)
se <- sqrt(diag(cov_m1))
尝试2:
mod1_rob <- coeftest(mod1, vcovHC = vcov(mod1, type = "HC0"))
最成功的是HC0
和vcov = sandwich
,但没有SE是正确的。
有什么建议吗?
编辑
我的输出如下(使用HC0
):
Estimate Std. Error z value Pr(>|z|)
(Intercept) 1.3281183 1.5441312 0.8601 0.389730
eei -0.0435529 0.0183359 -2.3753 0.017536 *
costofwar_log 0.2984376 0.1350518 2.2098 0.027119 *
cfughh -0.0380690 0.0130254 -2.9227 0.003470 **
roadskm 0.0020812 0.0010864 1.9156 0.055421 .
popdensity_log -0.4661079 0.1748682 -2.6655 0.007688 **
tkilled_log 1.0949084 0.2159161 5.0710 3.958e-07 ***
我要复制的Stata输出为:
Estimate Std. Error
(Intercept) 1.328 1.272
eei -0.044 0.015
costofwar_log 0.298 0.123
cfughh -0.038 0.018
roadskm 0.002 0.0001
popdensity_log -0.466 0.208
tkilled_log 1.095 0.209
找到数据集here,重新编码的变量为:
mod1_df <- table %>%
select(displaced, eei_01, costofwar, cfughh, roadskm, popdensity,
tkilled)
mod1_df$popdensity_log <- log(mod1_df$popdensity + 1)
mod1_df$tkilled_log <- log(mod1_df$tkilled + 1)
mod1_df$costofwar_log <- log(mod1_df$costofwar + 1)
mod1_df$eei <- mod1_df$eei_01*100
答案 0 :(得分:2)
在R中,您需要手动提供自由度校正,因此请尝试我从this source借来的方法:
dfa <- (G/(G - 1)) * (N - 1)/pm1$df.residual
# display with cluster VCE and df-adjustment
firm_c_vcov <- dfa * vcovHC(pm1, type = "HC0", cluster = "group", adjust = T)
coeftest(pm1, vcov = firm_c_vcov)
这里G
是数据集中的面板数,N
是观察数,pm1
是您的模型估计值。显然,您可以删除群集。
答案 1 :(得分:2)
Stata使用观察到的Hessian进行计算,glm.nb()
使用期望的Hessian。因此,bread()
函数使用的默认sandwich()
是不同的,从而导致不同的结果。还有其他一些R包使用观察到的hessian进行方差-协方差估计(例如gamlss
),但是这些R包没有为estfun()
包提供sandwich
方法。
因此,下面我简单地设置一个专用的bread_obs()
函数,该函数从negbin
对象中提取ML估计值,设置负对数似然率,并通过{{1} },然后从中计算出“面包”(省略log(theta)的估算值):
numDeriv::hessian()
使用该功能,我可以将bread_obs <- function(object, method = "BFGS", maxit = 5000, reltol = 1e-12, ...) {
## data and estimated parameters
Y <- model.response(model.frame(object))
X <- model.matrix(object)
par <- c(coef(object), "log(theta)" = log(object$theta))
## dimensions
n <- NROW(X)
k <- length(par)
## nb log-likelihood
nll <- function(par) suppressWarnings(-sum(dnbinom(Y,
mu = as.vector(exp(X %*% head(par, -1))),
size = exp(tail(par, 1)), log = TRUE)))
## covariance based on observed Hessian
rval <- numDeriv::hessian(nll, par)
rval <- solve(rval) * n
rval[-k, -k]
}
的输出(基于预期的粗麻布)与使用sandwich()
的输出(基于观察到的粗麻布)进行比较。
bread_obs()
与Stata相比仍存在细微差异,但可能是优化等方面的数值差异。
如果您为s_exp <- sandwich(mod1)
s_obs <- sandwich(mod1, vcov = bread_obs)
cbind("Coef" = coef(mod1), "SE (Exp)" = sqrt(diag(s_exp)), "SE (Obs)" = sqrt(diag(s_obs)))
## Coef SE (Exp) SE (Obs)
## (Intercept) 1.328 1.259 1.259
## eei -0.044 0.017 0.015
## costofwar_log 0.298 0.160 0.121
## cfughh -0.038 0.015 0.018
## roadskm 0.002 0.001 0.001
## popdensity_log -0.466 0.135 0.207
## tkilled_log 1.095 0.179 0.208
个对象创建新的专用bread()
方法
negbin
然后,如果您进行bread.negbin <- bread_obs
,则方法分派将使用此方法。