R의 표준 오류 클러스터링 (수동 또는 plm)


33

표준 오류 "클러스터링"과 R에서 실행하는 방법을 이해하려고합니다 (Stata에서는 사소합니다). RI에서 plm나 자신의 기능을 사용 하거나 작성하는 데 실패했습니다 . 패키지 의 diamonds데이터를 사용하겠습니다 ggplot2.

더미 변수로 고정 효과를 할 수 있습니다

> library(plyr)
> library(ggplot2)
> library(lmtest)
> library(sandwich)
> # with dummies to create fixed effects
> fe.lsdv <- lm(price ~ carat + factor(cut) + 0, data = diamonds)
> ct.lsdv <- coeftest(fe.lsdv, vcov. = vcovHC)
> ct.lsdv

t test of coefficients:

                      Estimate Std. Error  t value  Pr(>|t|)    
carat                 7871.082     24.892  316.207 < 2.2e-16 ***
factor(cut)Fair      -3875.470     51.190  -75.707 < 2.2e-16 ***
factor(cut)Good      -2755.138     26.570 -103.692 < 2.2e-16 ***
factor(cut)Very Good -2365.334     20.548 -115.111 < 2.2e-16 ***
factor(cut)Premium   -2436.393     21.172 -115.075 < 2.2e-16 ***
factor(cut)Ideal     -2074.546     16.092 -128.920 < 2.2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1 

또는 왼쪽과 오른쪽을 모두 의미하지 않고 (여기서 시간이 변하지 않는 회귀자가 없음) 자유도를 수정합니다.

> # by demeaning with degrees of freedom correction
> diamonds <- ddply(diamonds, .(cut), transform, price.dm = price - mean(price), carat.dm = carat  .... [TRUNCATED] 
> fe.dm <- lm(price.dm ~ carat.dm + 0, data = diamonds)
> ct.dm <- coeftest(fe.dm, vcov. = vcovHC, df = nrow(diamonds) - 1 - 5)
> ct.dm

t test of coefficients:

         Estimate Std. Error t value  Pr(>|t|)    
carat.dm 7871.082     24.888  316.26 < 2.2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1 

plm"시간"인덱스가 없기 때문에이 결과를 복제 할 수 없습니다 (즉, 이것은 실제로 패널이 아니며 오류 조건에서 공통적 인 편향을 가질 수있는 클러스터 일뿐입니다).

> plm.temp <- plm(price ~ carat, data = diamonds, index = "cut")
duplicate couples (time-id)
Error in pdim.default(index[[1]], index[[2]]) : 

또한 Stata의 cluster옵션 설명 (여기 설명)을 사용하여 클러스터 표준 오류로 내 자신의 공분산 행렬을 코딩하려고했습니다 . 이는 여기서 , si 클러스터 수, 는 잔차 위해 관찰 일정한 포함 예측기의 행 벡터이다 (이것은 또한 Wooldridge에서의 식 (7.22)로 나타나는 단면 패널 데이터UJ=ΣCLUSt의전자(R)의j 개의Ei∗xinceiith

V^cluster=(X′X)−1(∑j=1ncuj′uj)(X′X)−1
uj=∑cluster jei∗xinceiithxi). 그러나 다음 코드는 매우 큰 공분산 행렬을 제공합니다. 내가 가진 소수의 클러스터가 주어지면 이러한 매우 큰 값이 있습니까? plm한 가지 요소로 클러스터를 수행 할 수 없기 때문에 코드를 벤치마킹하는 방법을 잘 모르겠습니다.
> # with cluster robust se
> lm.temp <- lm(price ~ carat + factor(cut) + 0, data = diamonds)
> 
> # using the model that Stata uses
> stata.clustering <- function(x, clu, res) {
+     x <- as.matrix(x)
+     clu <- as.vector(clu)
+     res <- as.vector(res)
+     fac <- unique(clu)
+     num.fac <- length(fac)
+     num.reg <- ncol(x)
+     u <- matrix(NA, nrow = num.fac, ncol = num.reg)
+     meat <- matrix(NA, nrow = num.reg, ncol = num.reg)
+     
+     # outer terms (X'X)^-1
+     outer <- solve(t(x) %*% x)
+ 
+     # inner term sum_j u_j'u_j where u_j = sum_i e_i * x_i
+     for (i in seq(num.fac)) {
+         index.loop <- clu == fac[i]
+         res.loop <- res[index.loop]
+         x.loop <- x[clu == fac[i], ]
+         u[i, ] <- as.vector(colSums(res.loop * x.loop))
+     }
+     inner <- t(u) %*% u
+ 
+     # 
+     V <- outer %*% inner %*% outer
+     return(V)
+ }
> x.temp <- data.frame(const = 1, diamonds[, "carat"])
> summary(lm.temp)

Call:
lm(formula = price ~ carat + factor(cut) + 0, data = diamonds)

Residuals:
     Min       1Q   Median       3Q      Max 
-17540.7   -791.6    -37.6    522.1  12721.4 

Coefficients:
                     Estimate Std. Error t value Pr(>|t|)    
carat                 7871.08      13.98   563.0   <2e-16 ***
factor(cut)Fair      -3875.47      40.41   -95.9   <2e-16 ***
factor(cut)Good      -2755.14      24.63  -111.9   <2e-16 ***
factor(cut)Very Good -2365.33      17.78  -133.0   <2e-16 ***
factor(cut)Premium   -2436.39      17.92  -136.0   <2e-16 ***
factor(cut)Ideal     -2074.55      14.23  -145.8   <2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1 

Residual standard error: 1511 on 53934 degrees of freedom
Multiple R-squared: 0.9272, Adjusted R-squared: 0.9272 
F-statistic: 1.145e+05 on 6 and 53934 DF,  p-value: < 2.2e-16 

> stata.clustering(x = x.temp, clu = diamonds$cut, res = lm.temp$residuals)
                        const diamonds....carat..
const                11352.64           -14227.44
diamonds....carat.. -14227.44            17830.22

이것을 R에서 할 수 있습니까? 그것은 계량 경제학에서 상당히 일반적인 기술 이지만 ( 이 강의 에는 간단한 자습서가 있습니다) R에서 알아낼 수는 없습니다. 감사합니다!


7
@ricardh, 사용하고자하는 용어가 이미 통계에 사용되는지 여부를 확인하지 않은 것에 대해 모든 경제학자에게 저주. 이 문맥에서 군집은 그룹을 의미하며 군집 분석과 전혀 관련이 없기 때문에 rseek이 관련없는 결과를 제공 한 이유입니다. 따라서 클러스터링 태그를 제거했습니다. 패널 데이터 분석에 대해서는 plm 패키지를 확인하십시오 . 멋진 비네팅이 있으므로 원하는 것을 찾을 수 있습니다. 당신의 질문에 관해서는 당신이 원하는 것을 명확하지 않습니다. 그룹 표준 오류 내에서?
— mpiktas

@ ricardh,이 cluster옵션이 설명되어 있는 Stata의 일부 매뉴얼에 링크 할 수 있다면 많은 도움이 될 것 입니다. 나는 R에서 복제가 가능할 것이라고 확신한다.
— mpiktas

2
해당 댓글에 +1 경제학자들은 미친 것처럼 용어를 식민지화합니다. 때때로 악당을 고르기가 어렵습니다. Ii는 예를 들어 내가 factor아무 관련이 factanal없지만 범주화 된 변수를 참조 할 때까지 시간이 걸렸다 . 그러나 R의 군집은 군집 분석을 의미하며 k-means는 단지 분할 방법입니다 : statmethods.net/advstats/cluster.html . 나는 당신의 질문을 얻지 못하지만 클러스터는 그것과 관련이 없다고 생각합니다.
— hans0l0

@mpiktas, @ ran2-감사합니다! 질문을 명확히하기를 바랍니다. 간단히 말해서, 이미 존재하는 고정 된 효과 인 경우 "표준 오류 클러스터링"이 존재하는 이유는 무엇입니까?
— Richard Herron

1
"multiwayvcov"패키지의 cluster.vcov 함수는 원하는 것을 수행합니다.

답변:


29

plm프레임 워크를 사용하여 그룹별로 클러스터 된 화이트 표준 오류의 경우

coeftest(model.plm, vcov=vcovHC(model.plm,type="HC0",cluster="group"))

model.plmplm 모델은 어디에 있습니까 ?

이 링크 참조

http://www.inside-r.org/packages/cran/plm/docs/vcovHC 또는 plm 패키지 설명서

편집하다:

양방향 클러스터링 (예 : 그룹 및 시간)은 다음 링크를 참조하십시오.

http://people.su.se/~ma/clustering.pdf

다음은 클러스터 된 표준 오류에 대한 다양한 옵션을 설명하는 plm 패키지에 대한 또 다른 유용한 안내서입니다.

http://www.princeton.edu/~otorres/Panel101R.pdf

Stata에 대한 클러스터링 및 기타 정보는 여기에서 찾을 수 있습니다.

http://www.kellogg.northwestern.edu/faculty/petersen/htm/papers/se/se_programming.htm

편집 2 :

R과 stata를 비교하는 예는 다음과 같습니다. http://www.richard-bluhm.com/clustered-ses-in-r-and-stata-2/

또한 multiwayvcov도움 이 될 수 있습니다. 이 게시물은 유용한 개요를 제공합니다 : http://rforpublichealth.blogspot.dk/2014/10/easy-clustered-standard-errors-in-r.html

설명서에서 :

library(multiwayvcov)
library(lmtest)
data(petersen)
m1 <- lm(y ~ x, data = petersen)

# Cluster by firm
vcov_firm <- cluster.vcov(m1, petersen$firmid)
coeftest(m1, vcov_firm)
# Cluster by year
vcov_year <- cluster.vcov(m1, petersen$year)
coeftest(m1, vcov_year)
# Cluster by year using a formula
vcov_year_formula <- cluster.vcov(m1, ~ year)
coeftest(m1, vcov_year_formula)

# Double cluster by firm and year
vcov_both <- cluster.vcov(m1, cbind(petersen$firmid, petersen$year))
coeftest(m1, vcov_both)
# Double cluster by firm and year using a formula
vcov_both_formula <- cluster.vcov(m1, ~ firmid + year)
coeftest(m1, vcov_both_formula)

나 coeftest(model.plm, vcov=vcovHC(model.plm,type="HC0")) 에게도 coeftest(model.plm, vcov=vcovHC(model.plm,type="HC0",cluster="group"))동일한 결과를 낳습니다. 왜 그런지 아십니까?
— 피터 팬

1
people.su.se/~ma/clustering.pdf 링크 가 더 이상 작동하지 않습니다. 페이지 제목을 기억하십니까?
— MERose

8

많은 독서 끝에 lm프레임 워크 내에서 클러스터링을 수행하는 솔루션을 찾았습니다 .

Mahmood Arai 의 훌륭한 백서 에는 lm프레임 워크의 클러스터링에 대한 자습서 가 있으며 위의 지저분한 시도 대신 자유도 교정을 수행합니다. 그는 단방향 및 양방향 클러스터링 공분산 행렬에 대한 기능을 여기에 제공 합니다.

마지막으로, 컨텐츠는 무료로 제공되지 않지만 Angrist와 Pischke의 무해한 계량 경제학 은 클러스터링에 대한 섹션이있어 매우 도움이되었습니다.


블로그 게시물의 코드를 추가하려면 2015 년 4 월 27 일에 업데이트되었습니다 .

api=read.csv("api.csv") #create the variable api from the corresponding csv
attach(api) # attach of data.frame objects
api1=api[c(1:6,8:310),] # one missing entry in row nr. 7
modell.api=lm(API00 ~ GROWTH + EMER + YR_RND, data=api1) # creation of a simple linear model for API00 using the regressors Growth, Emer and Yr_rnd.

##creation of the function according to Arai:
clx <- function(fm, dfcw, cluster) {
    library(sandwich)
    library(lmtest)
    library(zoo)
    M <- length(unique(cluster))
    N <- length(cluster)
    dfc <- (M/(M-1))*((N-1)/(N-fm$rank)) # anpassung der freiheitsgrade
    u <- apply(estfun(fm),2, function(x) tapply(x, cluster, sum))
    vcovCL <-dfc * sandwich (fm, meat = crossprod(u)/N) * dfcw
    coeftest(fm, vcovCL)
}

clx(modell.api, 1, api1$DNUM) #creation of results.

1
Arai의 논문은 더 이상 온라인 상태가 아닙니다. 실제 링크를 제공 할 수 있습니까?
— MERose

@MERose-죄송합니다! 불행히도 우리는 PDF를 첨부 할 수 없습니다! 코드를 벤치마킹하는 이 블로그 게시물 을 찾았 습니다 . 코드를 포함하도록이 답변을 편집하겠습니다.
— Richard Herron

이 백서의 업데이트 된 버전 일 수 있습니다. Mahmood Arai, R을 사용한 클러스터 표준 오류 .
— gung-모니 티 복원

4

R에서 군집 된 표준 오류를 계산하는 가장 쉬운 방법은 수정 된 요약 함수를 사용하는 것입니다.

lm.object <- lm(y ~ x, data = data)
summary(lm.object, cluster=c("c"))

lm 프레임 워크에는 클러스터링에 대한 훌륭한 글 이 있습니다 . 이 사이트는 또한 단방향 및 양방향 클러스터링을 위해 수정 된 요약 기능을 제공합니다. 함수와 튜토리얼은 여기 에서 찾을 수 있습니다 .


1

time색인 이없는 경우 색인이 필요하지 않습니다 plm. 가상으로 가상 색인 을 추가하고 요청하지 않으면 사용되지 않습니다. 따라서이 전화 는 효과가 있습니다 .

> x <- plm(price ~ carat, data = diamonds, index = "cut")
 Error in pdim.default(index[[1]], index[[2]]) : 
  duplicate couples (time-id) 

그렇지 않은 경우를 제외하고의 버그가 발생했음을 나타냅니다 plm. (이 버그는 이제 SVN에서 수정되었습니다. 여기 에서 개발 버전 을 설치할 수 있습니다 .)

그러나 이것은 가상의 time색인 이 될 것이기 때문에 스스로 만들 수 있습니다.

diamonds$ftime <- 1:NROW(diamonds)  ##fake time

이제 이것은 작동합니다.

x <- plm(price ~ carat, data = diamonds, index = c("cut", "ftime"))
coeftest(x, vcov.=vcovHC)
## 
## t test of coefficients:
## 
##       Estimate Std. Error t value  Pr(>|t|)    
## carat  7871.08     138.44  56.856 < 2.2e-16 ***
## ---
## Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

중요 사항 : vcovHC.plm()에서 plm기본 추계 의지 아레야노는 그룹 SE들에 의해 클러스터. 이는 다른 것과 vcovHC.lm()의 sandwich(예를 들면 추정됩니다 vcovHC어떤 클러스터링이 분산 일관성 SE들입니다, 원래의 질문에 SE들)을.


이에 대한 별도의 접근 방식은 lm더미 변수 회귀 및 multiwayvcov 패키지를 고수하는 것 입니다.

library("multiwayvcov")
fe.lsdv <- lm(price ~ carat + factor(cut) + 0, data = diamonds)
coeftest(fe.lsdv, vcov.= function(y) cluster.vcov(y, ~ cut, df_correction = FALSE))
## 
## t test of coefficients:
## 
##                      Estimate Std. Error t value  Pr(>|t|)    
## carat                 7871.08     138.44  56.856 < 2.2e-16 ***
## factor(cut)Fair      -3875.47     144.83 -26.759 < 2.2e-16 ***
## factor(cut)Good      -2755.14     117.56 -23.436 < 2.2e-16 ***
## factor(cut)Very Good -2365.33     111.63 -21.188 < 2.2e-16 ***
## factor(cut)Premium   -2436.39     123.48 -19.731 < 2.2e-16 ***
## factor(cut)Ideal     -2074.55      97.30 -21.321 < 2.2e-16 ***
## ---
## Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

두 경우 모두 그룹별로 클러스터링 된 Arellano (1987) SE를 받게됩니다. 이 multiwayvcov패키지는 Arai의 원래 클러스터링 기능에서 직접적이고 중요한 발전입니다.

두 접근 방식에서 결과 분산 공분산 행렬을보고 다음과 같은 분산 추정치를 얻을 수 있습니다 carat.

vcov.plm <- vcovHC(x)
vcov.lsdv <- cluster.vcov(fe.lsdv, ~ cut, df_correction = FALSE)
vcov.plm
##          carat
## carat 19165.28
diag(vcov.lsdv)
##                carat      factor(cut)Fair      factor(cut)Good factor(cut)Very Good   factor(cut)Premium     factor(cut)Ideal 
##            19165.283            20974.522            13820.365            12462.243            15247.584             9467.263 

이 링크를 참조하십시오 : multiwayvcov는 감가 상각됩니다 : sites.google.com/site/npgraham1/research/code
— HoneyBuddha
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.