Phân cụm lỗi tiêu chuẩn trong R (bằng tay hoặc bằng plm)


33

Tôi đang cố gắng để hiểu lỗi "phân cụm" tiêu chuẩn và cách thực hiện trong R (đó là chuyện nhỏ trong Stata). Trong RI đã không thành công bằng cách sử dụng plmhoặc viết chức năng của riêng tôi. Tôi sẽ sử dụng diamondsdữ liệu từ ggplot2gói.

Tôi có thể thực hiện các hiệu ứng cố định với các biến giả

> 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 

hoặc bằng cách không có nghĩa là cả bên trái và bên phải (không có hồi quy bất biến thời gian ở đây) và điều chỉnh mức độ tự do.

> # 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 

Tôi không thể sao chép các kết quả này với plm, vì tôi không có chỉ số "thời gian" (nghĩa là đây không thực sự là một bảng điều khiển, chỉ là các cụm có thể có sai lệch chung trong các điều khoản lỗi của chúng).

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

Tôi cũng đã thử mã hóa ma trận hiệp phương sai của riêng mình với lỗi tiêu chuẩn được nhóm lại bằng cách sử dụng giải thích của Stata về clustertùy chọn của họ ( giải thích ở đây ), để giải quyếttrong đóbạn làj=clus

V^ctôibạnSter= =(X'X)-1(Σj= =1ncbạnj'bạnj)(X'X)-1
là vectơ hàng của các yếu tố dự đoán, bao gồm cả hằng số (điều này cũng xuất hiện dưới dạng phương trình (7.22 ) trongMặt cắt ngang và Dữ liệu bảngcủa Wooldridge). Nhưng đoạn mã sau cho ma trận hiệp phương sai rất lớn. Đây có phải là những giá trị rất lớn với số lượng cụm nhỏ tôi có không? Vì tôi không thểthực hiện các cụm theo một yếu tố, tôi không chắc cách đánh giá mã của mình. , n c si số cụm, e i là số dư choquan sát i t h x ibạnj= =ΣctôibạnSter jetôi*xtôincetôitôithxtôiplm
> # 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

Điều này có thể được thực hiện trong R? Đây là một kỹ thuật khá phổ biến trong toán kinh tế lượng (có một hướng dẫn ngắn gọn trong bài giảng này ), nhưng tôi không thể tìm ra nó trong R. Cảm ơn!


7
@ricardh, nguyền rủa tất cả các nhà kinh tế vì không kiểm tra xem thuật ngữ họ muốn sử dụng đã được sử dụng trong thống kê chưa. Cụm trong ngữ cảnh này có nghĩa là nhóm và hoàn toàn không liên quan đến phân tích cụm, đây là lý do tại sao rseek cho bạn kết quả không liên quan. Do đó tôi loại bỏ thẻ phân cụm. Đối với phân tích dữ liệu bảng điều khiển kiểm tra gói plm . Nó có một họa tiết đẹp, vì vậy bạn có thể tìm thấy những gì bạn muốn. Đối với câu hỏi của bạn không rõ ràng những gì bạn muốn. Trong phạm vi tiêu chuẩn nhóm?
mpiktas

@ricardh, nó sẽ giúp ích rất nhiều nếu bạn có thể liên kết với một số hướng dẫn sử dụng Stata nơi clustergiải thích tùy chọn này. Tôi chắc chắn rằng nó sẽ có thể sao chép trong R.
mpiktas

2
+1 cho nhận xét đó. các nhà kinh tế học thuộc địa thuật ngữ như điên. Mặc dù đôi khi thật khó để chọn nhân vật phản diện. Ii mất một lúc, ví dụ cho đến khi tôi nhận ra factorkhông có gì để làm factanalngoài việc đề cập đến các biến được phân loại. Tuy nhiên, cụm trong R đề cập đến phân tích cụm, k- mean chỉ là phương thức phân vùng: statmethods.net/advstats/cluster.html . Tôi không nhận được câu hỏi của bạn, nhưng tôi cũng đoán cụm không có gì để làm với nó.
hans0l0

@mpiktas, @ ran2 - Cảm ơn! Tôi hy vọng tôi đã làm rõ câu hỏi. Nói tóm lại, tại sao "phân cụm lỗi tiêu chuẩn" tồn tại nếu nó chỉ là các hiệu ứng cố định, đã tồn tại?
Richard Herron

1
Hàm cluster.vcov trong gói "multiwayvcov" thực hiện những gì bạn đang tìm kiếm.

Câu trả lời:


29

Đối với các lỗi tiêu chuẩn Trắng được nhóm theo nhóm với plmkhung thử

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

Ở đâu model.plm là một mô hình plm.

Xem thêm liên kết này

http://www.inside-r.org/packages/cran/plm/docs/vcovHC hoặc tài liệu gói plm

CHỈNH SỬA:

Để phân cụm hai chiều (ví dụ: nhóm và thời gian), xem liên kết sau:

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

Dưới đây là một hướng dẫn hữu ích khác cho gói plm giải thích cụ thể các tùy chọn khác nhau cho các lỗi tiêu chuẩn được nhóm:

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

Phân cụm và thông tin khác, đặc biệt là cho Stata, có thể được tìm thấy ở đây:

http://www.kellogg.northwestern.edu/facemony/peteren/htm/ con / se / se_programming.htmlm

EDIT 2:

Dưới đây là các ví dụ so sánh R và stata: http://www.richard-bluhm.com/clustered-ses-in-r-and-stata-2/

Ngoài ra, multiwayvcovcó thể hữu ích. Bài đăng này cung cấp một cái nhìn tổng quan hữu ích: http://rforpublichealth.blogspot.dk/2014/10/easy-clustered-stiteria-errors-in-r.html

Từ tài liệu:

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)

đối với tôi coeftest(model.plm, vcov=vcovHC(model.plm,type="HC0")) cũng như coeftest(model.plm, vcov=vcovHC(model.plm,type="HC0",cluster="group"))tạo ra kết quả giống hệt nhau. Bạn có biết tại sao lại như vậy không?
Peter Pan

1
Liên kết people.su.se/~ma/clustering.pdf không còn hoạt động. Bạn có nhớ tiêu đề của trang?
MERose

8

Sau khi đọc rất nhiều, tôi tìm thấy giải pháp cho việc phân cụm trong lmkhung.

Có một cuốn sách trắng tuyệt vời của Mahmood Arai cung cấp một hướng dẫn về phân cụm trong lmkhung, mà anh ta thực hiện với các chỉnh sửa mức độ tự do thay vì những nỗ lực lộn xộn của tôi ở trên. Anh ta cung cấp các chức năng của mình cho cả ma trận hiệp phương sai một và hai chiều ở đây .

Cuối cùng, mặc dù nội dung không có sẵn miễn phí, Kinh tế lượng vô hại của Angrist và Pischke có một phần về phân cụm rất hữu ích.


Cập nhật ngày 27/4/2015 để thêm mã từ bài đăng trên blog .

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
Giấy của Arai không còn trực tuyến nữa. Bạn có thể cung cấp các liên kết thực tế?
MERose

@Merose - Xin lỗi! Thật không may, chúng tôi không thể đính kèm pdf! Tôi tìm thấy bài viết blog này mà điểm chuẩn mã. Tôi sẽ chỉnh sửa câu trả lời này để bao gồm mã.
Richard Herron

Đây có thể là một phiên bản cập nhật của giấy trắng: Mahmood Arai, tiêu chuẩn Cluster-mạnh mẽ lỗi sử dụng R .
gung - Phục hồi Monica

4

Cách dễ nhất để tính toán các lỗi tiêu chuẩn được phân cụm trong R là sử dụng hàm tóm tắt đã sửa đổi.

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

Có một bài viết tuyệt vời về phân cụm trong khung lm. Trang web cũng cung cấp chức năng tóm tắt được sửa đổi cho cả phân cụm một và hai chiều. Bạn có thể tìm thấy chức năng và hướng dẫn ở đây .


1

Nếu bạn không có timechỉ mục, bạn không cần một chỉ mục: plmsẽ tự thêm một chỉ mục hư cấu và nó sẽ không được sử dụng trừ khi bạn yêu cầu. Vì vậy, cuộc gọi này sẽ hoạt động :

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

Ngoại trừ việc nó không có, điều đó cho thấy bạn đã gặp lỗi plm. (Lỗi này hiện đã được sửa trong SVN. Bạn có thể cài đặt phiên bản phát triển từ đây .)

Nhưng vì timedù sao đây cũng sẽ là một chỉ số hư cấu , chúng ta có thể tự tạo ra nó:

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

Bây giờ điều này hoạt động:

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

Lưu ý quan trọng : vcovHC.plm()theo plmý muốn theo mặc định Arellano được nhóm theo nhóm SE. Đó là khác nhau từ những gì vcovHC.lm()trong sandwichsẽ ước tính (ví dụ như các vcovHCDNhXH trong câu hỏi ban đầu), có nghĩa là các biến ngẫu nhiên DNhXH-phù hợp với không clustering.


Một cách tiếp cận riêng biệt cho vấn đề này là tuân theo lmcác hồi quy biến giả và gói 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

Trong cả hai trường hợp, bạn sẽ nhận được các SE Arellano (1987) với việc phân nhóm theo nhóm. Cácmultiwayvcov gói là một quá trình tiến hóa trực tiếp và quan trọng của chức năng phân nhóm gốc Arai của.

Bạn cũng có thể xem ma trận phương sai hiệp phương sai kết quả từ cả hai phương pháp, đưa ra ước tính phương sai giống nhau cho 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 

Vui lòng xem liên kết này: multiwayvcov không được dùng nữa: sites.google.com.vn/site/npgraham1/research/code
HoneyBuddha
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.