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 개의Eixinceiith

V^cluster=(XX)1(j=1ncujuj)(XX)1
uj=cluster jeixinceiithxi). 그러나 다음 코드는 매우 큰 공분산 행렬을 제공합니다. 내가 가진 소수의 클러스터가 주어지면 이러한 매우 큰 값이 있습니까? 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.