This work is licensed under the Creative Commons Attribution-ShareAlike 4.0 International License. To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/4.0/ or send a letter to Creative Commons, PO Box 1866, Mountain View, CA 94042, USA.
License: CC BY-SA 4.0
Sugestão de citação: FIGUEIREDO, Adriano Marcos Rodrigues. Exemplo Diferenças em diferenças do Torres-Reyna (2015): R e Python. Campo Grande-MS, Brasil: RStudio/Rpubs, 2021. Disponível em https://rpubs.com/amrofi/diff_in_diff_torres_reyna.
Neste exemplo, reproduzimos o script de aula do Prof. Torres-Reyna (TORRES-REYNA, 2015). Os dados vem das notas de aula (https://www.princeton.edu/~otorres/DID101R.pdf). Um exemplo parecido utilizando dados em painel pode ser visto em Figueiredo (2019).
# Exemplo de Dados de Corte Transversal
library(tidyr)
library(dplyr)
library(DT)
library(magrittr)
Os dados em painel, ou de combinação de seção cruzada e série temporal (SCST), ou também chamados de dados longitudinais, associam dados de diferentes unidades ou indivíduos para diferentes períodos de tempo.
Segue o exemplo de Torres-Reyna (2015) para os dados em Panel101.dta
, para 10 anos (1990-99) e 7 países (aqui designados pelas letras A até G). Primeiro chamaremos os dados.
library(foreign)
mydata <-read.dta("http://dss.princeton.edu/training/Panel101.dta")
datatable(mydata)
Agora, criaremos a variável dummy indicadora do ano em que o tratamento foi iniciado. Encorajamos os leitores a ler Waldinger (sd) e Wooldridge (2007) para o tratamento teórico.
Neste caso, assumiremos, como em Torres-Reyna (2015), que o tratamento iniciou em 1994. A variável dummy terá o nome time
e será criada em mydata
com valores 0 para year
menor que 1994 e valores 1 para year >= 1994
.
mydata$time = ifelse(mydata$year >= 1994, 1, 0)
Portanto, agora o mydata
tem 10 variáveis, e a variável time como se vê abaixo:
datatable(mydata[,c(1:2,10)])
Agora faremos uma variável para identificar os grupos “tratados”, chamada treated
. Ela é criada também como dummy com valores iguais a 1 para os grupos de países E, F e G, e zero para os demais. Assim, temos o código.
mydata$treated = ifelse(mydata$country == "E" |
mydata$country == "F" |
mydata$country == "G", 1, 0)
O leitor pode verificar que agora existem 11 variáveis em mydata
, e que os países E, F e G tem valores de treated
iguais a 1.
datatable(mydata[,c(1:2,10:11)])
Criaremos agora uma variável que fará a interação entre time
e treated
, ou seja, os anos em que houve tratamento e os países que sofreram o tratamento. Esta será a variável chave para o modelo diff-in-diff, a variável did
.
mydata$did = mydata$time * mydata$treated
write.csv(mydata,'mydata.csv')
Tipicamente, o modelo diff-in-diff será uma regressão do tipo (WALDINGER, sd):
\[
Resultado_{it} = \beta_1 + \beta_2.Tratamento_i + \beta_3.Periodo_t + + \beta_4.(Tratamento.Periodo)_{it} + \varepsilon
\] em que:
* \(Resultado\) é a nossa variável dependente;
* \(Tratamento\) é a dummy que indica a observação do grupo de tratamento;
* \(Periodo\) é a dummy que indica o período pós-tratamento;
* \(\beta\) são parâmetros a serem estimados;
* \(i\) e \(t\) são subscritos para a observação e o ano;
* \(\varepsilon\) é o resíduo ruído branco.
didreg = lm(y ~ treated + time + did, data = mydata)
summary(didreg)
##
## Call:
## lm(formula = y ~ treated + time + did, data = mydata)
##
## Residuals:
## Min 1Q Median 3Q Max
## -9.768e+09 -1.623e+09 1.167e+08 1.393e+09 6.807e+09
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 3.581e+08 7.382e+08 0.485 0.6292
## treated 1.776e+09 1.128e+09 1.575 0.1200
## time 2.289e+09 9.530e+08 2.402 0.0191 *
## did -2.520e+09 1.456e+09 -1.731 0.0882 .
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 2.953e+09 on 66 degrees of freedom
## Multiple R-squared: 0.08273, Adjusted R-squared: 0.04104
## F-statistic: 1.984 on 3 and 66 DF, p-value: 0.1249
Neste caso, não precisamos fazer a interação, o programa faz automaticamente.
didreg1 = lm(y ~ treated*time, data = mydata)
summary(didreg1)
##
## Call:
## lm(formula = y ~ treated * time, data = mydata)
##
## Residuals:
## Min 1Q Median 3Q Max
## -9.768e+09 -1.623e+09 1.167e+08 1.393e+09 6.807e+09
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 3.581e+08 7.382e+08 0.485 0.6292
## treated 1.776e+09 1.128e+09 1.575 0.1200
## time 2.289e+09 9.530e+08 2.402 0.0191 *
## treated:time -2.520e+09 1.456e+09 -1.731 0.0882 .
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 2.953e+09 on 66 degrees of freedom
## Multiple R-squared: 0.08273, Adjusted R-squared: 0.04104
## F-statistic: 1.984 on 3 and 66 DF, p-value: 0.1249
O coeficiente de ‘treated:time’ é a estimativa do differences-in-differences (did
no exemplo anterior). O efeito foi significativo a 10% com o tratamento tendo efeito negativo.
Chamarei o arquivo csv salvo no início do exemplo.
import numpy as np
import csv
import pandas
mydata = pandas.read_csv("mydata.csv")
print(mydata.head())
## Unnamed: 0 country year y ... op time treated did
## 0 1 A 1990 1342787840 ... 1 0 0 0
## 1 2 A 1991 -1899660544 ... 0 0 0 0
## 2 3 A 1992 -11234363 ... 0 0 0 0
## 3 4 A 1993 2645775360 ... 0 0 0 0
## 4 5 A 1994 3008334848 ... 0 1 0 0
##
## [5 rows x 13 columns]
Como gerei o csv após criar as variáveis em R, já tenho todas as variáveis para a regressão linear no Python.
Código para instalar o sklearn:
library(reticulate)
py_install("scikit-learn")
py_install("statsmodels")
py_install("statsmodels.formula.api")
import numpy as np
from sklearn.linear_model import LinearRegression
import statsmodels.formula.api as sm
import statsmodels.formula.api as sm
result = sm.ols(formula="y ~ treated + time + did", data=mydata).fit()
print(result.summary())
## OLS Regression Results
## ==============================================================================
## Dep. Variable: y R-squared: 0.083
## Model: OLS Adj. R-squared: 0.041
## Method: Least Squares F-statistic: 1.984
## Date: Mon, 29 Mar 2021 Prob (F-statistic): 0.125
## Time: 17:46:13 Log-Likelihood: -1623.7
## No. Observations: 70 AIC: 3255.
## Df Residuals: 66 BIC: 3264.
## Df Model: 3
## Covariance Type: nonrobust
## ==============================================================================
## coef std err t P>|t| [0.025 0.975]
## ------------------------------------------------------------------------------
## Intercept 3.581e+08 7.38e+08 0.485 0.629 -1.12e+09 1.83e+09
## treated 1.776e+09 1.13e+09 1.575 0.120 -4.75e+08 4.03e+09
## time 2.289e+09 9.53e+08 2.402 0.019 3.87e+08 4.19e+09
## did -2.52e+09 1.46e+09 -1.731 0.088 -5.43e+09 3.87e+08
## ==============================================================================
## Omnibus: 6.182 Durbin-Watson: 1.615
## Prob(Omnibus): 0.045 Jarque-Bera (JB): 7.779
## Skew: -0.304 Prob(JB): 0.0205
## Kurtosis: 4.516 Cond. No. 7.26
## ==============================================================================
##
## Notes:
## [1] Standard Errors assume that the covariance matrix of the errors is correctly specified.
FIGUEIREDO, Adriano Marcos Rodrigues. Econometria: exemplo de dados em painel em R - Torres-Reyna data. Campo Grande-MS,Brasil: RStudio/Rpubs, 2019. Disponível em http://rpubs.com/amrofi/Econometrics_panel_torres_reyna e em https://adrianofigueiredo.netlify.app/post/Econometrics_panel_torres_reyna/.
TORRES-REYNA, Oscar. Differences-in-Differences (using R). Princeton,NJ(USA): Princeton University, 2015. Disponível em: https://www.princeton.edu/~otorres/DID101R.pdf.
WALDINGER, Fabian. Lectures 3 - Differences-in-Differences. Munich (sd). Disponível em: https://www.fabianwaldinger.com/applied-econometrics. Acesso: March, 27th, 2021.
WOOLDRIDGE, J. Difference-in-Differences Estimation. NBER, 2007. Disponível em: https://www.nber.org/lecture/difference-differences-estimation e video em: https://vimeo.com/27776614. Acesso: March, 27th, 2021.