Análise de Dados em Painel

Resumo

Este tutorial apresenta técnicas para análise de dados em painel, abordando os seguintes modelos: modelo de dados empilhados (Pooled OLS), modelo de efeitos fixos (FE), modelo de efeitos fixos com diferença pela média, e modelo de efeitos aleatórios (RE). Também explora gráficos, testes de comparação entre os modelos e diagnósticos essenciais para validação da modelagem de dados em painel.

1 Introdução

A análise de dados em painel combina informações de corte transversal e séries temporais, permitindo explorar variações entre indivíduos ao longo do tempo. Este tutorial cobre os principais modelos para análise de dados em painel, suas especificidades, como escolher o modelo mais adequado, e técnicas para validar as estimativas.

Os modelos abordados incluem:

- Modelo Pooled OLS (dados empilhados): Assume que não há diferenças entre indivíduos.

- Modelo de Efeitos Fixos (FE): Captura variações intra-individuais, controlando para características invariantes.

- Modelo de Efeitos Aleatórios (RE): Assume que as diferenças entre indivíduos são parte do termo de erro.

2 Preparação do Ambiente

# Instalação e carregamento dos pacotes necessários
# install.packages("plm")
# install.packages("lmtest")
# install.packages("stargazer")
# install.packages("ggplot2")
library(plm)       # Modelos de painel
library(lmtest)    # Testes estatísticos
library(stargazer) # Resumos formatados
library(ggplot2)   # Gráficos
library(dplyr)
library(tseries)

3 Simulando Dados em Painel

Geraremos dados simulados com 10 indivíduos e 5 períodos, incluindo variáveis independentes e dependentes.

set.seed(123)
n_ind <- 10  # Número de indivíduos
n_time <- 5  # Número de períodos

# Criando identificadores
id <- rep(1:n_ind, each = n_time)
time <- rep(1:n_time, times = n_ind)

# Variáveis independentes e dependente
x1 <- rnorm(n_ind * n_time, mean = 5, sd = 2)
x2 <- rnorm(n_ind * n_time, mean = 3, sd = 1)
alpha <- rep(rnorm(n_ind, mean = 2, sd = 1), each = n_time)  # Efeitos fixos por indivíduo
epsilon <- rnorm(n_ind * n_time, mean = 0, sd = 0.5)         # Erro aleatório
y <- 1 + 0.5 * x1 + 0.3 * x2 + alpha + epsilon               # Variável dependente

# Criando o data frame
painel_data <- data.frame(id = as.factor(id), time, y, x1, x2)
head(painel_data)
  id time        y       x1       x2
1  1    1 4.917440 3.879049 3.253319
2  1    2 5.754834 4.539645 2.971453
3  1    3 6.426499 8.117417 2.957130
4  1    4 6.142902 5.141017 4.368602
5  1    5 6.010853 5.258575 2.774229
6  2    1 8.977467 8.430130 4.516471

4 Visualizando os Dados

Vamos criar gráficos para explorar a variação da variável dependente ( y ) por indivíduo e ao longo do tempo.

# Gráfico da variável dependente por indivíduo
ggplot(painel_data, aes(x = time, y = y, group = id, color = id)) +
  geom_line() +
  labs(title = "Evolução de y por indivíduo", x = "Tempo", y = "y") +
  theme_minimal()

# Relação entre y e x1
ggplot(painel_data, aes(x = x1, y = y, color = id)) +
  geom_point() +
  geom_smooth(method = "lm", se = FALSE) +
  labs(title = "Relação entre y e x1 por Indivíduo", x = "x1", y = "y") +
  theme_minimal()

# Relação entre y e x2
ggplot(painel_data, aes(x = x2, y = y, color = id)) +
  geom_point() +
  geom_smooth(method = "lm", se = FALSE) +
  labs(title = "Relação entre y e x2 por Indivíduo", x = "x2", y = "y") +
  theme_minimal()

5 Estimação dos Modelos

5.1 Modelo de Dados Empilhados (Pooled OLS)

pooled_model <- plm(y ~ x1 + x2, data = painel_data, model = "pooling", index = c("id", "time"))
summary(pooled_model)
Pooling Model

Call:
plm(formula = y ~ x1 + x2, data = painel_data, model = "pooling", 
    index = c("id", "time"))

Balanced Panel: n = 10, T = 5, N = 50

Residuals:
     Min.   1st Qu.    Median   3rd Qu.      Max. 
-1.927591 -0.482681  0.020014  0.406147  2.057491 

Coefficients:
            Estimate Std. Error t-value  Pr(>|t|)    
(Intercept) 3.214619   0.562758  5.7123 7.317e-07 ***
x1          0.375288   0.065959  5.6897 7.911e-07 ***
x2          0.283171   0.134893  2.0992   0.04119 *  
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Total Sum of Squares:    60.57
Residual Sum of Squares: 34.311
R-Squared:      0.43353
Adj. R-Squared: 0.40942
F-statistic: 17.9847 on 2 and 47 DF, p-value: 1.5839e-06

5.2 Modelo de Efeitos Fixos (FE)

fixed_model <- plm(y ~ x1 + x2, data = painel_data, model = "within", index = c("id", "time"))
summary(fixed_model)
Oneway (individual) effect Within Model

Call:
plm(formula = y ~ x1 + x2, data = painel_data, model = "within", 
    index = c("id", "time"))

Balanced Panel: n = 10, T = 5, N = 50

Residuals:
     Min.   1st Qu.    Median   3rd Qu.      Max. 
-0.951490 -0.324115 -0.031983  0.294215  0.972176 

Coefficients:
   Estimate Std. Error t-value  Pr(>|t|)    
x1 0.391179   0.041029  9.5342 1.264e-11 ***
x2 0.254890   0.088834  2.8693  0.006684 ** 
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Total Sum of Squares:    31.855
Residual Sum of Squares: 9.1797
R-Squared:      0.71183
Adj. R-Squared: 0.62841
F-statistic: 46.9331 on 2 and 38 DF, p-value: 5.412e-11
ef_individuais <- fixef(fixed_model)
print(ef_individuais)
     1      2      3      4      5      6      7      8      9     10 
2.9110 3.7240 3.5035 3.2526 2.4856 3.6928 2.5923 2.0081 3.4506 4.6100 

5.3 Modelo de Efeitos Aleatórios (RE)

random_model <- plm(y ~ x1 + x2, data = painel_data, model = "random", index = c("id", "time"))
summary(random_model)
Oneway (individual) effect Random Effect Model 
   (Swamy-Arora's transformation)

Call:
plm(formula = y ~ x1 + x2, data = painel_data, model = "random", 
    index = c("id", "time"))

Balanced Panel: n = 10, T = 5, N = 50

Effects:
                 var std.dev share
idiosyncratic 0.2416  0.4915 0.271
individual    0.6501  0.8063 0.729
theta: 0.737

Residuals:
     Min.   1st Qu.    Median   3rd Qu.      Max. 
-1.145076 -0.340879 -0.010716  0.295653  1.004308 

Coefficients:
            Estimate Std. Error z-value  Pr(>|z|)    
(Intercept) 3.221781   0.440943  7.3066  2.74e-13 ***
x1          0.390007   0.039997  9.7509 < 2.2e-16 ***
x2          0.257182   0.086189  2.9839  0.002846 ** 
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Total Sum of Squares:    33.841
Residual Sum of Squares: 10.923
R-Squared:      0.67723
Adj. R-Squared: 0.66349
Chisq: 98.6131 on 2 DF, p-value: < 2.22e-16
# Resgatando os efeitos aleatórios individuais
ef_aleatorios <- ranef(random_model)
print(ef_aleatorios)
          1           2           3           4           5           6 
-0.29040115  0.46601090  0.26306540  0.02636017 -0.68642817  0.43743091 
          7           8           9          10 
-0.58585269 -1.13162219  0.21152084  1.28991598 

6 Comparação entre os Modelos

6.1 Teste F (Efeitos Fixos vs. Pooled)

O F test for individual effects é usado para verificar se há efeitos individuais significativos no modelo de dados em painel. Esse teste avalia se as diferenças entre os indivíduos (ou unidades) são estatisticamente significativas.

  1. Hipóteses do teste:

    • Hipótese nula (H₀): Não há efeitos individuais significativos, ou seja, as diferenças entre os indivíduos não afetam a variável dependente (y).

    • Hipótese alternativa (H₁): Existem efeitos individuais significativos, ou seja, as diferenças entre os indivíduos influenciam a variável dependente (y).

pFtest(fixed_model, pooled_model)

    F test for individual effects

data:  y ~ x1 + x2
F = 11.559, df1 = 9, df2 = 38, p-value = 1.794e-08
alternative hypothesis: significant effects
  • Estatística F e p-valor:

    • O valor do F (11.559) indica a magnitude da variação explicada pelos efeitos individuais em comparação com o erro residual.

    • O p-valor (1.794e-08) é muito baixo (menor que 0,05), levando à rejeição da hipótese nula com alto nível de confiança.

  • Conclusão:

    • evidências estatísticas fortes de que os efeitos individuais são significativos. Isso significa que as diferenças entre os indivíduos (ou unidades) têm impacto na variável dependente (y) e, portanto, um modelo que considere esses efeitos (como o modelo de efeitos fixos ou aleatórios) é mais apropriado do que um modelo Pooled OLS, que não leva em conta essas diferenças.

6.2 Teste de Hausman (Efeitos Fixos vs. Efeitos Aleatórios)

O Teste de Hausman é utilizado para decidir entre os modelos de efeitos fixos (FE) e efeitos aleatórios (RE) em uma análise de dados em painel. Ele verifica se as estimativas dos coeficientes do modelo de efeitos aleatórios são consistentes em relação ao modelo de efeitos fixos.

Hipóteses do teste:

  • Hipótese nula (H₀): O modelo de efeitos aleatórios (RE) é consistente e, portanto, apropriado.

  • Hipótese alternativa (H₁): O modelo de efeitos aleatórios (RE) é inconsistente, indicando que o modelo de efeitos fixos (FE) é mais apropriado.

phtest(fixed_model, random_model)

    Hausman Test

data:  y ~ x1 + x2
chisq = 0.036784, df = 2, p-value = 0.9818
alternative hypothesis: one model is inconsistent
  • Resultados do teste:

    • Estatística qui-quadrado (chisq): 0.036784

    • Graus de liberdade (df): 2

    • p-valor: 0.9818 (muito maior que 0,05)

  • Conclusão:

    • O p-valor alto (0.9818) indica que não há evidências suficientes para rejeitar a hipótese nula.

    • Isso significa que o modelo de efeitos aleatórios (RE) é consistente e apropriado para os dados.

6.3 Teste Breusch-Pagan (Efeitos Aleatórios vs. Pooled)

O Teste de Lagrange Multiplier (LM) ou Teste de Breusch-Pagan para dados em painel é usado para decidir entre o modelo de efeitos aleatórios (RE) e o modelo de dados empilhados (Pooled OLS). Ele verifica a existência de variância significativa nos efeitos aleatórios.

Hipóteses do teste:

  • Hipótese nula (H₀): Não há variância significativa nos efeitos aleatórios (modelo Pooled OLS é apropriado).

  • Hipótese alternativa (H₁): Existe variância significativa nos efeitos aleatórios (modelo de efeitos aleatórios é mais apropriado).

plmtest(pooled_model, type = "bp")

    Lagrange Multiplier Test - (Breusch-Pagan)

data:  y ~ x1 + x2
chisq = 43.965, df = 1, p-value = 3.343e-11
alternative hypothesis: significant effects
  • Resultados do teste:

    • Estatística qui-quadrado (chisq): 43.965

    • Graus de liberdade (df): 1

    • p-valor: 3.343e-11 (muito menor que 0,05)

  • Conclusão:

    • O p-valor muito baixo (3.343e-11) indica que rejeitamos a hipótese nula.

    • Isso significa que há evidências de que a variância dos efeitos aleatórios é significativa, o que justifica o uso do modelo de efeitos aleatórios (RE) ao invés do modelo Pooled OLS.

Observação:

  • Este teste complementa o Teste de Hausman. Juntos, ambos os testes ajudam a decidir entre os três principais modelos de painel:

    1. Pooled OLS (LM Test).

    2. Efeitos Fixos (Hausman Test).

    3. Efeitos Aleatórios (LM e Hausman Test).

7 Diagnósticos dos Modelos

7.1 Verificando Autocorrelação

pbgtest(random_model)

    Breusch-Godfrey/Wooldridge test for serial correlation in panel models

data:  y ~ x1 + x2
chisq = 2.4123, df = 5, p-value = 0.7896
alternative hypothesis: serial correlation in idiosyncratic errors
  • O p-valor alto (0.7896) sugere que não rejeitamos a hipótese nula.

  • Isso significa que não há evidências estatísticas de correlação serial nos erros idiossincráticos.

7.2 Verificando Heterocedasticidade

bptest(random_model)

    studentized Breusch-Pagan test

data:  random_model
BP = 1.2764, df = 2, p-value = 0.5282
  • O p-valor alto (0.5282) indica que não rejeitamos a hipótese nula.

  • Isso significa que não há evidências estatísticas de heterocedasticidade nos resíduos do modelo de efeitos aleatórios.

7.3 Verificando Normalidade dos Resíduos

# Histograma dos resíduos
residuals_re <- residuals(random_model)
ggplot(data.frame(residuals_re), aes(x = residuals_re)) +
  geom_histogram(aes(y = ..density..), bins = 20, color = "black", fill = "skyblue") +
  geom_density(color = "red") +
  labs(title = "Distribuição dos Resíduos (Modelo RE)", x = "Resíduos", y = "Densidade") +
  theme_minimal()

# Teste Jarque-Bera
jarque.bera.test(residuals_re)

    Jarque Bera Test

data:  residuals_re
X-squared = 0.049819, df = 2, p-value = 0.9754

Como o p-valor (0.9754) é muito maior do que o nível de significância típico (geralmente α=0.05), não rejeitamos a hipótese nula.

  • Conclusão: Os resíduos do modelo podem ser considerados normais. Isso indica que não há evidências de violação da normalidade com base no Teste Jarque-Bera.

8 Resumo dos Modelos

Apresentamos os resultados dos modelos em uma tabela.

stargazer(pooled_model, fixed_model, random_model, type = "text",
          title = "Resultados dos Modelos de Dados em Painel",
          dep.var.labels = "y",
          column.labels = c("Pooled OLS", "Efeitos Fixos", "Efeitos Aleatórios"),
          digits = 3)

Resultados dos Modelos de Dados em Painel
=============================================================================
                                   Dependent variable:                       
             ----------------------------------------------------------------
                                            y                                
                   Pooled OLS           Efeitos Fixos      Efeitos Aleatórios
                      (1)                    (2)                  (3)        
-----------------------------------------------------------------------------
x1                  0.375***               0.391***             0.390***     
                    (0.066)                (0.041)              (0.040)      
                                                                             
x2                  0.283**                0.255***             0.257***     
                    (0.135)                (0.089)              (0.086)      
                                                                             
Constant            3.215***                                    3.222***     
                    (0.563)                                     (0.441)      
                                                                             
-----------------------------------------------------------------------------
Observations           50                     50                   50        
R2                   0.434                  0.712                0.677       
Adjusted R2          0.409                  0.628                0.663       
F Statistic  17.985*** (df = 2; 47) 46.933*** (df = 2; 38)     98.613***     
=============================================================================
Note:                                             *p<0.1; **p<0.05; ***p<0.01

9 Considerações Finais

Neste tutorial, exploramos diferentes modelos para análise de dados em painel, incluindo Pooled OLS, Efeitos Fixos e Efeitos Aleatórios. Também realizamos testes estatísticos para comparar os modelos e diagnósticos essenciais para validação. A escolha entre efeitos fixos e aleatórios depende das características dos dados e dos resultados de testes como o de Hausman.

A análise de dados em painel permite capturar dinâmicas de curto e longo prazo, sendo uma ferramenta poderosa para estudos econômicos, sociais e financeiros.