diferenças-em-diferenças

Author

Igor Viveiros

Published

November 17, 2023

1 Introdução

  • Diferenças em Diferenças, ou simplesmente DiD, tem por objetivo comparar a variação no tempo da variável de resultado entre tratamento e controle, sendo assim, essa é uma combinação de:

    • uma comparação transversal (comparar uma amostra que foi tratada com um grupo de controle não tratado)

    • uma comparação temporal (comparar o grupo de tratamento com ele mesmo, antes e depois do tratamento)

  • A diferença antes e depois no grupo de tratamento recebe uma correção, levando em conta a diferença antes e depois no grupo de controle, eliminando o problema da tendência. Para obter uma estimativa imparcial do efeito do tratamento, é necessário fazer uma suposição de tendência paralela. Isso significa que, sem a mudança no ambiente, a mudança na variável de resultado teria sido a mesma para os dois grupos (resultado contrafactual).

  • No Dif-in-Dif não há a necessidade que os mesmos indivíduos sejam repetidos a cada cross-section entretanto, ou seja, não há a necessidade de um painel balanceado. No entanto, alguma agregação que faça sentido tem der possível, isto é os indivíduos dos grupos de controle e tratamento têm de pertencer a algum grupo em que a agregação seja palatável.

  • Pode ser usado tanto num contexto de dados experimentais e não-experimentais, bem como na situação de um quase-experimento:

  • Dados experimentais: participação das unidades no grupo de tratamento ou controle é feita de maneira aleatória como, por exemplo, em ensaios clínicos;

  • Dados não experimentais: participação das unidades no grupo de tratamento ou controle é feita com base em algum critério de seleção como, em geral, definição de grupos alvo por políticas públicas. Geralmente a participação no grupo de tratamento está atrelada ao nível da variável resposta;

  • Quase-experimento: situação em que a ocorrência de um evento é não-esperada e permite gerar grupos de tratamento e controle de forma automática. Esses eventos podem ter origem em mudanças que ocorrem na própria natureza, alterações institucionais (não correlacionadas com a variável resposta). Em suma, variações exógenas ao que se está estudando é que determina ou não em que grupo a unidade estará

- A principal pergunta aqui é: o que teria acontecido com as unidades tratadas se não tivessem recebido tratamento? Ou seja: se tivéssemos um contrafactual,
- Se pudéssemos observar tal situação conseguiríamos estimar com precisão o efeito de um tratamento qualquer sobre as unidades.
- O problema fundamental da inferência causal é que os possíveis resultados potenciais no contrafactual não podem ser observados. Podemos estimar funções desse contrafactual usando outras observações. Isso é o que chamamos de grupo de controle. Um conjunto de unidades que não receberam o tratamento mas que mimetizam o comportamento dos tratados,
- A validade da abordagem DiD está intimamente relacionada à semelhança entre o grupo de tratamento e o grupo de controle.
- Principal hipótese: trajetória temporal da variável de resultado para o grupo de controle representa o que teria ocorrido com variável de resultado dos tratados na ausência do tratamento: Common Trend Hypothesis ou Tendências paralelas.

Por quê usar grupos de controle é tão importante?

  • Quando se vai analisar o efeito de uma intervenção a primeira curiosidade que vem à mente é: vamos comparar como os indivíduos estavam antes e como estão agora,

  • Embora seja fácil, e tentador, realizar essa análise ela pode (e provavelmente deverá) produzir resultados ruim. Vejamos um exemplo:

    • Entre 2002 e e 2003 o número de casos de tuberculose nas comunidades do Rio de Janeiro estavam aumentando,
    • Em meados de 2003 o governo implementa o programa DOTS, que tem por objetivo diagnosticar e tratar os caso,
    • Regitrou-se o tamanho da população sob risco e o número de casos,
    • Esses registros foram realizados entre abril e outubro de cada ano

FIGURA

Qual o efeito real do programa?


  • Compara o antes e o depois pode ser errôneo pois os fenômenos sofrem de trajetória prévia, provocada por outros fatores, que nem sempre conseguimos controloar (confound factors)

  • Assim, por mais que controlemos por tudo aquilo que achamos relevante, sempre pode existir um fator não controlado e não observado que afeta o fenômeno

  • Se não isolarmos corretamente esse efeito nossa medição acerca dos impactos do programa estará viesada!

  • A solução é procurar um bom grupo de controle! Por bom grupo de controle entende-se obsevações que apresentem trajetória temporal da variável de resultado \(Y\) similar ao grupo de tratamento. Em outra palavras: Tendências paralelas.


  • Notação: \[ Y_{T,0} \ \text{: representa a variável de interesse do grupo de tratamento antes da interveção,}\] \[ Y_{T,1} \ \text{: representa a variável de interesse do grupo de tratamento depois da interveção,}\] \[ Y_{C,0} \ \text{: representa a variável de interesse do grupo de controle antes da interveção,}\] \[ Y_{C,1} \ \text{: representa a variável de interesse do grupo de controle depois da interveção}\]

  • Vamos assumir que cada grupo tenha seu prórprio nível (ou efeito fixo):

    • \(\alpha_C\): nível para grupo de controle,
    • \(\alpha_T\): nível para grupo de tratamento,
  • Vamos supor que essas observações sofram de uma trajetória prévia comum denotada por \(\gamma\).

  • Asuuma que o verdadeiro efeito da intervenção é o parâmetros \(\delta\).

Desta forma, vamos considerar os seguintes valores para a variável de interesse:

  • \(Y_{C,0} = \alpha_C + u_{C,0}\): Valor para grupo de controle antes da interveção;

  • \(Y_{T,0} = \alpha_T + u_{C,0}\): Valor para grupo de trantamento antes da interveção;

  • \(Y_{C,1} = \alpha_C + \gamma + u_{C,1}\): Valor para grupo de controle pós interveção;

  • \(Y_{T,1} = \alpha_T + \gamma + \delta + u_{T,1}\): Valor para grupo de tratamento pós interveção;

  • Se considerarmos apenas os tratados antes e depois estamos calculando o seguinte efeito:

\[ Y_{T,1} - Y_{T,0} = (\alpha_T + \gamma + \delta + u_{T,1}) - (\alpha_T + u_{C,0})\] \[ Y_{T,1} - Y_{T,0} = (\gamma + \delta + u_{T,1} - u_{C,0})\] * Se tomarmos a esperança:

\[ E[Y_{T,1} - Y_{T,0}] = E[(\gamma + \delta + u_{T,1}) - (\alpha_T + u_{T,0})] = \gamma + \delta\]

  • O resultado final fica poluído pela trajetória prévia,

  • Desta forma, precisamos de uma dupla diferença para remover o parâmetro \(\delta\):

\[ (Y_{T,1} - Y_{T,0}) - (Y_{C,1} - Y_{C,0}) = \] \[ [(\alpha_T + \gamma + \delta + u_{T,1}) - (\alpha_T + u_{T,0})] - [(\alpha_C + \gamma + u_{C,1}) - (\alpha_C + u_{T,0})] = \] \[ \delta + u_{T,1} - u_{T,0} - u_{C,1} + u_{T,0} \] \[ E[\delta + u_{T,1} - u_{T,0} - u_{C,1} + u_{T,0}] = \delta\]

No formato de uma regressão, a equação de um modelo diff-in-diff fica:

\[Y_{s,t}= \alpha_C + \alpha_T Treatment_s + \gamma d_t + \delta(Treatment \times d_t) + \beta X_{s,t} + u_{s,t}\]

onde \(s = (C,T)\) representa o índice de indivíduo, \(t = \{1,\ldots,T\}\) é o índice de tempow e:

  • Treatment é uma dummy que igual a to 1 se a observação pertence ao grupo de tratamento,

  • \(d_t\) é uma dummy que é igual a para o período anterior ao tratamento para cada unidade,

  • \(X_{s,t}\) são variáveis de controle.


2 Exemplo: Banco de dados simulados

  • Para demonstrar o uso e a validação de técnicas de DiD, geraremos um banco de dados simulados em que sabemos que a variável de tratamento exerce efeito sobre a variável dependente. Assim, observaremos 40 indivíduos ao longo dos periodos 1 a 100. Para tanto, serão usados os pacotes dplyr e sjPlot.
Code
library(dplyr)
library(sjPlot)

{
  set.seed(12345)
  T = 100 # no de periodos
  N = 40 # no de casos
  
  dat = expand.grid( t = 1:T,i = 1:N)
  
  # Simulando uma tendencia temporal comum AR(1) 
  time.trend = as.numeric(arima.sim(n=T,list(ar = c(0.4,0.5), ma=c(0.6,0.5))))*3+0.7*(1:T)
  
  dat = mutate(dat,
               group = ifelse(i > N/2,"treat","control"), #Definição do controle e tratamento
               treat = 1L*(group == "treat"), 
               exp = 1L*(t > T/2), # Observação após a plicação do tratamento
               treat_exp = exp*treat, #Identificador de que a unidade foi tratada
               mu.t = time.trend[t], #Tendencia temporal
               eps = rnorm(n(),0,15), # Erro aleatório
               y = mu.t + treat*40 + treat_exp*50 + eps # Variável dependente em função do tratamento
  )
}



sample_n(dat, 5) |> tab_df(title = "Estrutura do banco simulado")
Estrutura do banco simulado
t i group treat exp treat_exp mu.t eps y
50 31 treat 1 0 0 23.72 3.56 67.27
8 21 treat 1 0 0 18.62 -3.45 55.18
22 26 treat 1 0 0 19.90 22.88 82.78
62 40 treat 1 1 1 33.21 -5.65 117.56
37 22 treat 1 0 0 28.61 -11.48 57.13

Em que \(t\) é o tempo da observação, \(i\) é o indicador do individuo, \(group\) e \(treat\) indica se a observação está no grupo controle ou tratamento, \(exp\) indica se o periodo observado já ouve exposição ao tratamento, \(mu.t\) indica a tendência temporal simulada, \(eps\) o erro aleatório e \(y\) é nossa variável dependente.

  • O primeiro passo da avaliação do modelo é conferir se existem tendencias paralelas entre o grupo controle e tratamento. Para tanto, podemos utilizar uma análise visual para comparar a variável dependente de ambos os grupos.
Code
show.plot = function(dat,label="", show.means=TRUE) {
  library(ggplot2)
  gdat = dat %>%
    group_by(group, t,exp,treat) %>%
    summarize(y = mean(y))
  
  gg = ggplot(gdat, aes(y=y,x=t, color= group)) +
    geom_line() +
    geom_vline(xintercept=T/2) +
    theme_bw() +
    annotate("text",x=T/4, y = 0.9*max(gdat$y), label=label)
  
  if (show.means) {
    y.pre.tr <<- mean(filter(gdat,treat==1, exp==0)$y) %>% round(1)
    y.exp.tr <<- mean(filter(gdat,treat==1, exp==1)$y) %>% round(1)
    y.pre.co <<- mean(filter(gdat,treat==0, exp==0)$y) %>% round(1)
    y.exp.co <<- mean(filter(gdat,treat==0, exp==1)$y) %>% round(1)
    gg = gg +
      annotate("label", x=T/4, y=y.pre.tr+15,label=y.pre.tr) +
      annotate("label", x=T/4, y=y.pre.co-15,label=y.pre.co) +
      annotate("label", x=T*0.75, y=y.exp.tr+15,label=y.exp.tr) +
      annotate("label", x=T*0.75, y=y.exp.co-15,label=y.exp.co)
  }
  gg
}
show.plot(dat)

  • Nos dados simulados utilizados, as tendências pré-tratamento são quase perfeitamente paralelas, aumentando a confiança de que o uso de um estimador de DiD é apropriado. Na prática, podemos implementar uma estimação de DiD por meio de uma regressão linear:

\[y = \beta_0 + \beta_1 exp + \beta_2 treat + \gamma (exp\times treat) +\epsilon\]

Code
library(broom)

lm(y ~ exp*treat, data=dat) |> 
  tab_model()
  y
Predictors Estimates CI p
(Intercept) 27.88 26.63 – 29.13 <0.001
exp 22.46 20.69 – 24.23 <0.001
treat 39.47 37.70 – 41.24 <0.001
exp × treat 51.19 48.69 – 53.70 <0.001
Observations 4000
R2 / R2 adjusted 0.815 / 0.815
  • O efeito estimado pelo do tratamento é dados pela estimativa da interação entre \(exp\) x \(treat\), que representa o \(\Delta\). No caso, observamos um efeito médio do tratamento de aumento de 51,2 pontos na variável dependente, sendo essa estatisticamente significante a um p-valor menor que 0,001.

  • Para validar o modelo estimado, realizaremos uma regressão linear com as mesmas especificações, mas substituindo a variável dependente por \(mu.t\), que sabemos ser completamente independente do tratamento, só variando de acordo com o tempo. Nesse caso, o termo interativo deve ser 0.

\[y = \theta_0 mu.t + \theta_1(mu.t \times treat) + \beta {exp} + \beta {treat} + \beta (exp \times treat) +\epsilon\]

Code
lm(y ~ treat*mu.t +  exp*treat, data=dat) |> 
  tab_model()
  y
Predictors Estimates CI p
(Intercept) 0.21 -1.34 – 1.76 0.790
treat 40.21 38.02 – 42.41 <0.001
mu t 1.01 0.96 – 1.06 <0.001
exp -1.43 -3.11 – 0.26 0.097
treat × mu t -0.03 -0.09 – 0.04 0.412
treat × exp 51.84 49.46 – 54.22 <0.001
Observations 4000
R2 / R2 adjusted 0.903 / 0.903
  • Como podemos ver, a estimação do parametro interativoé zero, indicando que não há efeito do tratamento sobre \(mu.t\), como deveria ser esperado.

Adicionando confounders

Agora, adicionaremos variáveis de confusão, que atrapalharão a identificação de tendências paralelas. Assim, adicionaremos a variável de confusão \(x\) à simulação dos dados.

Code
dat = dat %>% mutate(
  x = ifelse(treat,-t, t)+runif(n())*2,
  y = mu.t + treat*40 + treat_exp*50 + 0.8*x + eps
)
show.plot(dat, show.means=FALSE, label="Tendências prévias\n não paralelas")

  • Agora, estimaremos o mesmo modelo de regressão linear apresentado anteriormente.
Code
lm(log(y) ~ exp*treat, data=dat) |> 
  tab_model()
Warning in log(y): NaNs produzidos
  log(y)
Predictors Estimates CI p
(Intercept) 3.76 3.73 – 3.78 <0.001
exp 0.91 0.87 – 0.95 <0.001
treat 0.03 -0.01 – 0.07 0.092
exp × treat -0.32 -0.37 – -0.27 <0.001
Observations 3980
R2 / R2 adjusted 0.451 / 0.450
  • Note que agora nós obtivemos uma estimação errada do efeito do tratamento, indicando como efeito um decressimo médio de 28,8 pontos em \(y\). Contudo, como estamos operando por meio de regressões, podemos adicionar controles a fim de controlar a influência de outras variáveis sobre nossas estimações. Agora, o modelo será especificado por:

\[y = \beta{exp} + \beta{treat} + \beta(exp\times treat) + \beta x+\epsilon\]

Code
lm(y ~ exp*treat+x, data=dat) |> 
  tab_model()
  y
Predictors Estimates CI p
(Intercept) 27.42 25.72 – 29.12 <0.001
exp 21.59 18.79 – 24.39 <0.001
treat 40.35 37.52 – 43.18 <0.001
x 0.82 0.77 – 0.86 <0.001
exp × treat 52.92 47.91 – 57.93 <0.001
Observations 4000
R2 / R2 adjusted 0.671 / 0.671
  • Note que a estimação do efeito do tratamento agora ocorre dentro do intervalo de confiança apontado pelo primeiro modelo, em que não havia interferência de uma variável de confusão. Isto porque, ao controlarmos a influência de \(x\) nos dados por meio da regressão, mantemos novamente as tendências paralelas.
Code
dat$y.org = dat$y
m0 <- lm(y~x+ exp*treat,data=dat)
dat$y = dat$y - m0$coefficients[2]*dat$x
show.plot(dat,show.means = FALSE, label="Tendências prévias\n com a\n inserção de controles")

  • O diagnóstico pode ser feito de forma direta, utilizando o pacote ParallelTrendsPlot, que constroi os gráficos com e sem o controle das variávies de controle
Code
# install.packages("remotes")
# remotes::install_github("skranz/glueformula")
# remotes::install_github("skranz/ParallelTrendsPlot")

library(ParallelTrendsPlot)

dat$y=dat$y.org
pt.dat = parallel.trends.data(dat,cvars="x")
parallel.trends.plot(pt.dat) + theme_bw()

  • Podemos fazer um teste simples de tendências paralelas por meio de um modelo com interação tripla. No modelo sem controles, temos um resultado significativo da variável de tempo e de sua interação com o tratamento. Já no modelo com controles, essa relação desaparece, indicando que o tempo não está influenciando o tratamento.
Code
lm(y.org ~ t*treat*exp ,data=dat)|>tab_model(
  show.ci = F,title = "Sem controles"
)
lm(y.org ~ x+ t*treat*exp ,data=dat)|>tab_model(
  show.ci = F,title = "Com controles"
)
Sem controles
  y org
Predictors Estimates p
(Intercept) 17.38 <0.001
t 1.24 <0.001
treat 41.05 <0.001
exp -53.90 <0.001
t × treat -1.66 <0.001
t × exp 0.72 <0.001
treat × exp 50.01 <0.001
(t × treat) × exp 0.06 0.417
Observations 4000
R2 / R2 adjusted 0.798 / 0.797
Com controles
  y org
Predictors Estimates p
(Intercept) 16.66 <0.001
x 0.73 0.092
t 0.52 0.232
treat 41.07 <0.001
exp -53.80 <0.001
t × treat -0.21 0.808
t × exp 0.72 <0.001
treat × exp 49.91 <0.001
(t × treat) × exp 0.06 0.399
Observations 4000
R2 / R2 adjusted 0.798 / 0.797

Teste simples de tendências paralelas


3 Validação do modelo

  • Todo e qualquer modelo estatítico deve ser validado, isto é, deve-se analisar se ele atende às hipóteses necessárias para que suas estimativas sejam consistente!

  • Sendo assim, sempre realizamos um conjunto de testes para validar os modelos. No caso da abordagem DiD, tal validação está intimamente relacionada à semelhança entre o grupo de tratamento e o grupo de controle. Portanto, algumas verificações de plausibilidade devem ser realizadas:

  • calcular o Placebo-DiD para períodos sem mudança no ambiente;

  • para dados em que séries temporais são mais longas: verifique e demonstre as tendências temporais paralelas;

  • use um grupo de controle alternativo (se disponível): a estimativa deve ser a mesma;

  • substitua \(Y\) por um resultado alternativo que seja definitivamente independente do tratamento (o estimador DiD deve ser 0).