You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

R中sandwich::vcovHC处理观测计数时生成错误VCOV矩阵问题

加权线性模型中sandwich::vcovHC未正确处理观测计数权重的问题

我在处理含大量重复观测的线性模型时,为节省内存将观测计数作为权重(加权OLS等价于重复观测的OLS),数据量达40万条且模型需多次调用。未加权模型m与加权模型m.w的点估计完全一致,但sandwich::vcovHC生成的方差-协方差(VCOV)矩阵差异显著,显然未正确将权重视为观测重复计数。

最小可复现示例

rm(list = ls())
x <- c(1, 1, 1, 1, 2:10) # 观测1重复4次
y <- c(15, 15, 15, 15, 13, 36, 31, 37, 63, 66, 80, 91, 94)
x.uniq <- x[-(1:3)]
y.uniq <- y[-(1:3)]
w <- c(4, rep(1, 9))
m <- lm(y ~ x)
m.w <- lm(y.uniq ~ x.uniq, weights = w)

coef(m) - coef(m.w) # 点估计完全一致

round(sandwich::vcovHC(m, type = "HC0"), 2)
#            (Intercept)     x
#(Intercept)        5.06 -0.53
#x                 -0.53  0.11

round(sandwich::vcovHC(m.w, type = "HC0"), 2) # 结果差异极大

理论正确的VCOV计算

手动实现White渐近三明治公式,无论是否按重复计数加权,结果均与未加权模型的vcovHC输出一致:

# 未加权版本
br <- solve(crossprod(model.matrix(m)))
me <- crossprod(model.matrix(m) * resid(m))
V <- br %*% me %*% br
round(V, 2)
#            (Intercept) x.uniq
#(Intercept)        5.06  -0.53
#x.uniq            -0.53   0.11

# 加权版本(正确处理重复计数)
br.w <- solve(crossprod(model.matrix(m.w) * sqrt(weights(m.w))))
me.w <- crossprod(model.matrix(m.w) * resid(m.w) * sqrt(weights(m.w)))
V.w <- br.w %*% me.w %*% br.w
round(V.w, 2)
#            (Intercept) x.uniq
#(Intercept)        5.06  -0.53
#x.uniq            -0.53   0.11

问题根源

通过手动计算meat部分验证,问题出在sandwich::meatHC函数的处理逻辑:

X <- model.matrix(m)
X.w <- model.matrix(m.w)
res <- rowMeans(estfun(m)/X)
res.w <- rowMeans(estfun(m.w)/X.w)
omega <- res^2
omega.w <- res.w^2

meat <- crossprod(sqrt(omega) * X) / nrow(X)
meat.w <- crossprod(sqrt(omega.w) * X.w) / nrow(X.w)

all.equal(meat, meatHC(m, type = "HC0")) # TRUE
all.equal(meat.w, meatHC(m.w, type = "HC0")) # TRUE

疑问

是否遗漏了传递给estfun的参数?或者需要自定义omega向量来修正加权模型的meat计算?


内容的提问来源于stack exchange,提问作者André V. Kostyrka

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 10:55:04