Estou tentando entender o erro padrão "clustering" e como executar no R (é trivial no Stata). No RI, não obtive sucesso usando plm
ou escrevendo minha própria função. Vou usar os diamonds
dados do ggplot2
pacote.
Eu posso fazer efeitos fixos com variáveis fictícias
> 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
ou des-significando os lados esquerdo e direito (sem regressores invariantes no tempo aqui) e corrigindo graus de liberdade.
> # 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
Não consigo replicar esses resultados com plm
, porque não tenho um índice de "tempo" (ou seja, esse não é realmente um painel, apenas clusters que poderiam ter um viés comum em termos de erro).
> plm.temp <- plm(price ~ carat, data = diamonds, index = "cut")
duplicate couples (time-id)
Error in pdim.default(index[[1]], index[[2]]) :
Também tentei codificar minha própria matriz de covariância com erro padrão em cluster usando a explicação da Stata sobre sua cluster
opção ( explicada aqui ), que é resolver onde , si o número de clusters, é o resíduo para a observação e é o vetor de linha dos preditores, incluindo a constante (isso também aparece como equação (7.22) na seção transversal de Wooldridge e nos dados do paineluj=ΣcLusterjei*xinceiith
plm
criar clusters com um fator, não sei como fazer o benchmark do meu código.
> # 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
Isso pode ser feito em R? É uma técnica bastante comum em econometria (há um breve tutorial nesta palestra ), mas não consigo descobrir isso em R. Obrigado!
fonte
cluster
opção é explicada. Estou certo de que seria possível replicar em R.factor
que não tinha nada a ver com isso,factanal
mas se refere a variáveis categorizadas. No entanto, cluster em R se refere à análise de cluster, k-means é apenas o método de particionamento: statmethods.net/advstats/cluster.html . Não entendi sua pergunta, mas também acho que o cluster não tem nada a ver com isso.Respostas:
Para erros padrão brancos agrupados por grupo com a
plm
estrutura, tenteonde
model.plm
é um modelo plm.Veja também este link
http://www.inside-r.org/packages/cran/plm/docs/vcovHC ou a documentação do pacote plm
EDITAR:
Para clustering bidirecional (por exemplo, grupo e hora), consulte o seguinte link:
http://people.su.se/~ma/clustering.pdf
Aqui está outro guia útil para o pacote plm especificamente que explica opções diferentes para erros padrão em cluster:
http://www.princeton.edu/~otorres/Panel101R.pdf
Clustering e outras informações, especialmente para Stata, podem ser encontradas aqui:
http://www.kellogg.northwestern.edu/faculty/petersen/htm/papers/se/se_programming.htm
EDIT 2:
Aqui estão exemplos que comparam R e stata: http://www.richard-bluhm.com/clustered-ses-in-r-and-stata-2/
Além disso,
multiwayvcov
pode ser útil. Esta publicação fornece uma visão geral útil: http://rforpublichealth.blogspot.dk/2014/10/easy-clustered-standard-errors-in-r.htmlA partir da documentação:
fonte
coeftest(model.plm, vcov=vcovHC(model.plm,type="HC0"))
, além decoeftest(model.plm, vcov=vcovHC(model.plm,type="HC0",cluster="group"))
produzir resultados idênticos. Você sabe por que esse é o caso?Depois de muita leitura, encontrei a solução para fazer clustering dentro da
lm
estrutura.Há um excelente white paper de Mahmood Arai que fornece um tutorial sobre clustering na
lm
estrutura, que ele faz com correções de graus de liberdade, em vez de minhas tentativas confusas acima. Ele fornece suas funções para matrizes de covariância de cluster unidirecional e bidirecional aqui .Finalmente, embora o conteúdo não esteja disponível gratuitamente, o Mostly Harmless Econometrics de Angrist e Pischke possui uma seção sobre clustering que foi muito útil.
Atualize em 27/04/2015 para adicionar código da postagem do blog .
fonte
A maneira mais fácil de calcular erros padrão em cluster no R é usar a função de resumo modificada.
Há um excelente post sobre clustering na estrutura lm. O site também fornece a função de resumo modificada para clustering unidirecional e bidirecional. Você pode encontrar a função e o tutorial aqui .
fonte
Se você não possui um
time
índice, não precisa de um:plm
adicionará um fictício por si só e não será usado a menos que você o solicite. Portanto, esta chamada deve funcionar :Exceto que não, o que sugere que você encontrou um bug
plm
. (Este bug foi corrigido no SVN. Você pode instalar a versão de desenvolvimento a partir daqui .)Mas como esse seria um
time
índice fictício de qualquer maneira, podemos criá-lo por nós mesmos:Agora isso funciona:
Nota importante :
vcovHC.plm()
naplm
vontade pela estimativa padrão Arellano agrupados por SEs grupo. Que é diferente do quevcovHC.lm()
emsandwich
estimará (por exemplo, asvcovHC
SEs na pergunta original), que é SEs heterocedasticidade consistente sem clustering.Uma abordagem separada disso é a
lm
regressão de variáveis fictícias e o pacote multiwayvcov .Nos dois casos, você obterá os SEs de Arellano (1987) com agrupamento por grupo. O
multiwayvcov
pacote é uma evolução direta e significativa das funções de clustering originais do Arai.Você também pode examinar a matriz de variância-covariância resultante de ambas as abordagens, produzindo a mesma estimativa de variância para
carat
:fonte