ข้อผิดพลาดมาตรฐานการจัดกลุ่มใน 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 

หรือตามความหมายทั้งด้านซ้ายและด้านขวา (ไม่มี regressors คงที่ที่นี่) และแก้ไของศาอิสระ

> # 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 จำนวนกลุ่มเป็นส่วนที่เหลือ สำหรับการสังเกตและเป็นเวกเตอร์แถวของตัวทำนายรวมถึงค่าคงที่ (ซึ่งจะปรากฏเป็นสมการ (7.22) ในCross Sectionของ Wooldridge และ Panel DataยูJ=ΣลิตรUsทีอีอาร์เจอีฉัน*xฉันnอีฉันฉันทีเอช

V^ล.ยูsเสื้ออีR=(X'X)-1(ΣJ=1nยูJ'ยูJ)(X'X)-1
ยูJ=Σล.ยูsเสื้ออีR Jอีผม* * * *xผมnอีผมผมเสื้อชั่วโมงxผม) แต่รหัสต่อไปนี้ให้เมทริกซ์ความแปรปรวนร่วมที่มีขนาดใหญ่มาก ค่าที่สูงมากเหล่านี้มีให้กับกลุ่มเล็ก ๆ ที่ฉันมีหรือไม่? เนื่องจากฉันไม่สามารถ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? มันเป็นเทคนิคที่ใช้กันทั่วไปในเศรษฐมิติ (มีการสอนสั้น ๆ ในการบรรยายนี้ ) แต่ฉันไม่สามารถเข้าใจได้ในอาร์ขอบคุณ!


7
@ricardh สาปแช่งนักเศรษฐศาสตร์ทุกคนที่ไม่ได้ตรวจสอบว่ามีการใช้คำที่พวกเขาต้องการใช้ในสถิติหรือไม่ คลัสเตอร์ในบริบทนี้หมายถึงกลุ่มและไม่เกี่ยวข้องกับการวิเคราะห์กลุ่มทั้งหมดนี่คือเหตุผลที่ rseek ให้ผลลัพธ์ที่ไม่เกี่ยวข้องกับคุณ ดังนั้นฉันลบแท็กการจัดกลุ่ม สำหรับการวิเคราะห์ข้อมูลแผงตรวจสอบPLM แพคเกจ มันเป็นบทความที่ดีดังนั้นคุณอาจพบสิ่งที่คุณต้องการ สำหรับคำถามของคุณยังไม่ชัดเจนว่าคุณต้องการอะไร ภายในข้อผิดพลาดมาตรฐานของกลุ่ม?
mpiktas

@ricardh มันจะช่วยได้มากถ้าคุณสามารถลิงค์ไปยังคู่มือของ Stata ที่clusterตัวเลือกนี้ได้รับการอธิบาย ฉันแน่ใจว่ามันจะเป็นไปได้ที่จะทำซ้ำใน R.
mpiktas

2
+1 สำหรับความคิดเห็นนั้น นักเศรษฐศาสตร์ตั้งอาณานิคมศัพท์อย่างบ้าคลั่ง แม้ว่าบางครั้งมันก็ยากที่จะเลือกคนร้าย ฉันใช้เวลาสักครู่เช่นจนกว่าฉันจะรู้ว่าfactorไม่มีอะไรเกี่ยวข้องfactanalแต่อ้างอิงถึงตัวแปรที่จัดหมวดหมู่ อย่างไรก็ตามคลัสเตอร์ใน R หมายถึงการวิเคราะห์กลุ่ม K-หมายถึงเป็นเพียงวิธีการแบ่งพาร์ทิชัน: statmethods.net/advstats/cluster.html ฉันไม่ได้รับคำถามของคุณ แต่ฉันเดาด้วยว่าคลัสเตอร์ไม่มีส่วนเกี่ยวข้อง
hans0l0

@mpiktas, @ ran2 - ขอบคุณ! ฉันหวังว่าฉันจะอธิบายคำถามให้ชัดเจน กล่าวโดยย่อว่าเหตุใด "การจัดกลุ่มข้อผิดพลาดมาตรฐาน" จึงมีอยู่หากเป็นเพียงเอฟเฟกต์คงที่ซึ่งมีอยู่แล้ว
Richard Herron

1
ฟังก์ชัน cluster.vcov ในแพ็คเกจ "multiwayvcov" ทำในสิ่งที่คุณกำลังมองหา

คำตอบ:


29

สำหรับข้อผิดพลาดมาตรฐาน White ที่ทำคลัสเตอร์โดยกลุ่มพร้อมplmลองเฟรมเวิร์ก

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

ที่model.plmเป็นรูปแบบ PLM

ดูลิงค์นี้

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ไม่ทำงานอีกต่อไป คุณจำชื่อของหน้าได้หรือไม่?
ลด

8

หลังจากอ่านเป็นจำนวนมากฉันพบวิธีแก้ปัญหาสำหรับการทำคลัสเตอร์ภายในlmกรอบ

มีกระดาษสีขาวที่ยอดเยี่ยมโดย Mahmood Arai ที่ให้การสอนเกี่ยวกับการจัดกลุ่มในlmกรอบซึ่งเขาทำกับการแก้ไของศาอิสระแทนการพยายามยุ่งของฉันข้างต้น เขายังมีฟังก์ชั่นของเขาสำหรับทั้งหนึ่งและสองวิธีการฝึกอบรมการจัดกลุ่มความแปรปรวนที่นี่

ในที่สุดแม้ว่าเนื้อหาจะไม่มีให้บริการฟรี แต่Angrist และเศรษฐมิติที่ไม่เป็นอันตรายที่สุดของ Pischkeมีส่วนในการจัดกลุ่มที่มีประโยชน์มาก


Update เมื่อวันที่ 2015/04/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 - ขออภัย! น่าเสียดายที่เราไม่สามารถแนบไฟล์ PDF ได้! ฉันพบโพสต์บล็อกนี้ซึ่งเป็นเกณฑ์มาตรฐาน ฉันจะแก้ไขคำตอบนี้เพื่อรวมรหัส
Richard Herron

นี้อาจจะเป็นรุ่นปรับปรุงของกระดาษสีขาว: ลอยอาราอิข้อผิดพลาดมาตรฐานคลัสเตอร์แข็งแกร่งโดยใช้ R
gung - Reinstate Monica

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พระทัยโดยประมาณการค่าเริ่มต้นเรลลาคลัสเตอร์โดย SEs กลุ่ม ซึ่งเป็นที่แตกต่างจากสิ่งที่vcovHC.lm()ในsandwichจะประมาณการ (เช่นvcovHCSEs ในคำถามเดิม) ที่เป็น SEs heteroscedasticity-สอดคล้องกับไม่มีการจัดกลุ่ม


วิธีการที่แยกต่างหากสำหรับสิ่งนี้คือการยึดติดกับ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) SEs พร้อมการจัดกลุ่มตามกลุ่ม multiwayvcovแพคเกจเป็นวิวัฒนาการโดยตรงและที่สำคัญของอาราอิของฟังก์ชั่นการจัดกลุ่มเดิม

คุณยังสามารถดูเมทริกซ์ความแปรปรวนร่วม - ความแปรปรวนร่วมจากทั้งสองวิธีโดยให้ผลการประมาณค่าความแปรปรวนแบบเดียวกันสำหรับ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.