Buenos y malos controles

El uso de dagitty nos ayuda a identificar por qué variables tenemos que condicionar/estratificar. Pero veamos algunos ejemplos si wmulados para que nos quede claro

Intro

Eliminar los caminos de asociación no causales.

Counfounder (Fork)

DAG

Show the code
#| echo: true

dag1 <- dagify(
  x ~  z, 
  y ~ z + x,
  exposure = "x",
  outcome = "y",
  coords = list(
    x = c(
      x = 1,
      z = 2,
      y = 3
    ),
    y = c(
      x = 1, 
      z = 2,
      y = 1
  )
))

#TODO poner las coordenadas de los nodos
ggdag(dag1) + theme_dag()

usamos dagitty o ggdag_adjustment_set.

Show the code
#| echo: true

dagitty:: adjustmentSets(dag1, exposure = "x", outcome = "y")
#> { z }
Show the code
ggdag_adjustment_set(dag1, exposure = "x", outcome = "y")

El modelo correcto dado este dag es ajustar por Z. Veamos si es cierto, simulando la estructura del dag.

Mediator o chain

DAG

Show the code
#| echo: true

dag_med <- dagify(
  z ~  x, 
  y ~ z ,
  coords = list(
    x = c(
      x = 1,
      z = 2,
      y = 3
    ),
    y = c(
      x = 1, 
      z = 1,
      y = 1
  )
))

#TODO poner las coordenadas de los nodos
ggdag(dag_med) + theme_dag()

usamos dagitty o ggdag_adjustment_set.

Cuando tenemos un “mediator” podemos estar interesado en el efecto total o en el efecto directo.

efecto total

Show the code
#| echo: true

dagitty:: adjustmentSets(dag_med, exposure = "x", outcome = "y", effect = "total")
#>  {}
Show the code
ggdag_adjustment_set(dag_med, exposure = "x", outcome = "y", effect = "total") +
  theme_dag()

efecto_directo

Show the code
dagitty:: adjustmentSets(dag_med, exposure = "x", outcome = "y", effect = "direct")
#> { z }
Show the code
ggdag_adjustment_set(dag_med, exposure = "x", outcome = "y", effect = "direct") +
  theme_dag()

Simulemos

Ponemos que el efecto total de x sobre y es 6, pero que está mediado sólo por z, y que el efecto directo de x sobre y es 0.

Efecto total es sin ajustar por z y el efecto directo es ajustando por z

Collider

Normalmente “Don’t touch the collider !!”

DAG

Show the code
collider_dag <- dagify(
  z ~ x + y ,
  coords = list(
    x = c(
      x = 1,
      z = 2,
      y = 3
    ),
    y = c(
      x = 1, 
      z = 2,
      y = 1
  )
)
)

#TODO poner las coordenadas de los nodos
ggdag(collider_dag) + theme_dag()

Show the code
dagitty:: adjustmentSets(collider_dag, exposure = "x", outcome = "y")
#>  {}
Show the code
ggdag_adjustment_set(collider_dag, exposure = "x", outcome = "y")

En el siguiente ejemplo, donde hay un collider, el verdadero efecto de x sobre y es 0 por construcción, pero si ajustamos por el collider se abre el camino no causal y tenemos sesgo.

Parásito de la precisión

Hay veces en que ajustar por pre-treatments es perjudicial. Si no hay variables de confusión “ocultas” se produce una parasitación de la precisión

DAG

Show the code
dag2 <- dagify(
  x ~  z, 
  y ~  x,
  coords = list(
    x = c(
      x = 1,
      z = 1,
      y = 3
    ),
    y = c(
      x = 1, 
      z = 2,
      y = 1
  )
)
)

#TODO poner las coordenadas de los nodos
ggdag(dag2) + theme_dag()

Show the code
dagitty:: adjustmentSets(dag2, exposure = "x", outcome = "y")
#>  {}
Show the code
ggdag_adjustment_set(dag2, exposure = "x", outcome = "y")

Simulemos para ver mejor la diferencia

Amplificación del sesgo

A veces, si ajustamos por un pretreatment pero hay una variable de confusión no observada, podemos incurrir en amplificación del sesgo

DAG

Show the code
dag3 <- dagify(
  x ~  z + u, 
  y ~  x + u,
  coords = list(
    x = c(
      x = 1,
      z = 1,
      u = 2,
      y = 3
    ),
    y = c(
      x = 1, 
      z = 2,
      u = 1.5,
      y = 1
  )
)
)


#TODO poner las coordenadas de los nodos
ggdag(dag3) + theme_dag()

Show the code
dagitty:: adjustmentSets(dag3, exposure = "x", outcome = "y")
#> { u }
Show the code
ggdag_adjustment_set(dag3, exposure = "x", outcome = "y")

Tenemos que ajustar por u, pero u

Simulemos para ver mejor la diferencia

Y vemos que se produce la amplificación del sesgo