我正在分析一个数据集,其中数据聚集在几个组(区域中的城镇)中。数据集如下所示:
R> df <- data.frame(x = rnorm(10),
y = 3*rnorm(x),
groups = factor(sample(c('0','1'), 10, TRUE)))
R> head(df)
x y groups
1 -0.8959 1.54 1
2 -0.1008 -2.73 1
3 0.4406 0.44 0
4 0.0683 1.62 1
5 -0.0037 -0.20 1
6 -0.8966 -2.34 0
我希望我的lm()估计值考虑到组内的类内相关性,为此我使用函数cl()
来获取lm()
并返回强健的聚类协方差矩阵(原始{{ 3}}):
cl <- function(fm, cluster) {
library(sandwich)
M <- length(unique(cluster))
N <- length(cluster)
K <- fm$rank
dfc <- (M/(M-1))*((N-1)/(N-K-1))
uj <- apply(estfun(fm), 2, function(x) tapply(x, cluster, sum));
vcovCL <- dfc * sandwich(fm, meat = crossprod(uj)/N)
return(vcovCL)
}
现在,
output <- lm(y ~ x, data = df)
clcov <- cl(output, df$groups)
coeftest(output, clcov, nrow(df) - 1)
给了我需要的估计。现在的问题是我想使用模型进行预测,我需要使用新的协方差矩阵clcov
来计算预测的标准误差。也就是说,我需要
predict(output, se.fit = TRUE)
但使用clcov
代替vcov(output)
。像vcov() <-
这样的东西是完美的。
当然,我可以编写自己的函数来做预测,但我只是想知道是否有更实用的方法允许我使用签名lm
的方法(如arm :: sim)。 / p>
答案 0 :(得分:5)
预测中的se.fit不是使用vcov矩阵计算的,而是使用qr分解和残差方差。这也适用于vcov()函数:它将来自summary.lm()的未缩放的cov矩阵与残差方差一起使用,并使用那些。并且,从QR分解再次计算未缩放的cov矩阵。
所以我担心答案是“不,除了编写自己的功能之外别无选择”。您无法真正设置vcov矩阵,因为它在需要时会重新计算。然而,编写自己的函数是相当微不足道的。
predict.rob <- function(x,clcov,newdata){
if(missing(newdata)){ newdata <- x$model }
m.mat <- model.matrix(x$terms,data=newdata)
m.coef <- x$coef
fit <- as.vector(m.mat %*% x$coef)
se.fit <- sqrt(diag(m.mat%*%clcov%*%t(m.mat)))
return(list(fit=fit,se.fit=se.fit))
}
我没有使用predict()函数来避免不必要的计算。无论如何,它不会过多地缩短代码。
答案 1 :(得分:5)
我稍微修改了上面的代码,以便与预测函数更加一致 - 这样你就不会在newdata数据框中输入结果的值
predict.rob <- function(x,clcov,newdata){
if(missing(newdata)){ newdata <- x$model }
tt <- terms(x)
Terms <- delete.response(tt)
m.mat <- model.matrix(Terms,data=newdata)
m.coef <- x$coef
fit <- as.vector(m.mat %*% x$coef)
se.fit <- sqrt(diag(m.mat%*%clcov%*%t(m.mat)))
return(list(fit=fit,se.fit=se.fit))}