R 中 vcov() 函数的结果是如何计算的?

How is the result of the vcov() function in R computed?

我想知道如何手动计算当我在 lm 对象上调用 R 中的 vcov() 函数时返回的内容,即方差-协方差矩阵。

对角线条目非常简单,只需要把st。每个参数的误差并将其平方。例如,对于方差-协方差矩阵的项 (z,z) 下的估计,只需将 z 的估计系数的标准误差 (0.1096658) 取其平方即可计算得出。但是非对角线条目呢?有人可以提供代码来手动计算这些吗?

# Minimal working example code
library(data.table)
df <- data.table(y = runif(100, 0, 100),
                 x = runif(100, 0, 100),
                 z = runif(100, 0, 100))
coef(lm(y ~ x + z, df)) # coefficients
coef(summary(lm(y ~ x + z, df)))[,2] # standard errors
vcov(lm(y ~ x + z, df)) # variance-covariance matrix

# Example result
coef(lm(y ~ x + z, df))
(Intercept)           x           z 
54.44460066  0.03052479 -0.11197309 

coef(summary(lm(y ~ x + z, df)))[,2]
(Intercept)           x           z 
  8.4668880   0.1077858   0.1096658 

vcov(lm(y ~ x + z, df))
            (Intercept)            x            z
(Intercept)  71.6881931 -0.576781121 -0.585380616
x            -0.5767811  0.011617776 -0.001059506
z            -0.5853806 -0.001059506  0.012026594

查看函数的详细信息似乎是未缩放的协方差乘以 sigma 平方(如果完整情况为假):

suppressMessages(library(data.table))
df <- data.table(y = runif(100, 0, 100),
                 x = runif(100, 0, 100),
                 z = runif(100, 0, 100))
stats:::vcov.summary.lm
#> function (object, complete = TRUE, ...) 
#> .vcov.aliased(object$aliased, object$sigma^2 * object$cov.unscaled, 
#>     complete = complete)
#> <bytecode: 0x5619b28eec88>
#> <environment: namespace:stats>
stats:::.vcov.aliased
#> function (aliased, vc, complete = TRUE) 
#> {
#>     if (complete && NROW(vc) < (P <- length(aliased)) && any(aliased)) {
#>         cn <- names(aliased)
#>         VC <- matrix(NA_real_, P, P, dimnames = list(cn, cn))
#>         j <- which(!aliased)
#>         VC[j, j] <- vc
#>         VC
#>     }
#>     else vc
#> }
#> <bytecode: 0x5619b3644430>
#> <environment: namespace:stats>
vcov(mod<-lm(y ~ x + z, df))
#>             (Intercept)             x             z
#> (Intercept)  54.1734049 -0.4767886045 -0.4498457055
#> x            -0.4767886  0.0089655548  0.0005973927
#> z            -0.4498457  0.0005973927  0.0082190981
summary(mod)$cov.unscaled* summary(mod)$sigma^2
#>             (Intercept)             x             z
#> (Intercept)  54.1734049 -0.4767886045 -0.4498457055
#> x            -0.4767886  0.0089655548  0.0005973927
#> z            -0.4498457  0.0005973927  0.0082190981

reprex package (v2.0.1)

于 2021 年 10 月 1 日创建

对于“手动计算”,您可以查看此


library(data.table)
df     = data.table(y = runif(100, 0, 100),
                    x = runif(100, 0, 100),
                    z = runif(100, 0, 100))
mod    = lm(y ~ ., df)
X      = cbind(1, as.matrix(df[, -1]))
invXtX = solve(crossprod(X))
coef   = invXtX %*% t(X) %*% df$y
resid  = df$y - X %*% coef
df.res = nrow(X) - ncol(X)
manual = invXtX * sum(resid**2)/(df.res)
funct  = vcov(mod)
all.equal(manual, funct, check.attributes = F)# should be TRUE