2.1 Objetivos de aprendizaje

Al finalizar este capítulo, serás capaz de:

  • Definir y construir Diagramas Acíclicos Dirigidos (DAGs)
  • Distinguir entre causalidad y asociación
  • Identificar confusores usando DAGs
  • Aplicar las reglas de d-separación

2.2 ¿Qué es un DAG?

Un Diagrama Acíclico Dirigido (DAG, por sus siglas en inglés) es una representación gráfica de las relaciones causales entre variables.

NotaDefinición

Un DAG es un grafo donde:

  • Dirigido: Las flechas indican la dirección de la causalidad
  • Acíclico: No hay ciclos (no puedes volver a una variable siguiendo las flechas)

2.2.1 Componentes de un DAG

Código
library(ggdag)
library(ggplot2)

# DAG simple
dag <- dagify(
  Y ~ X + C,
  X ~ C,
  coords = list(
    x = c(X = 0, Y = 2, C = 1),
    y = c(X = 0, Y = 0, C = 1)
  )
)

ggdag(dag) +
  theme_dag() +
  labs(title = "DAG con exposición (X), resultado (Y) y confusor (C)")
Figura 2.1: Componentes básicos de un DAG

2.3 Causalidad vs Asociación

2.3.1 Asociación

Dos variables están asociadas si conocer el valor de una proporciona información sobre el valor de la otra.

\[P(Y|X) \neq P(Y)\]

2.3.2 Causalidad

Una variable causa otra si intervenir sobre la primera cambia la distribución de la segunda.

\[P(Y|do(X)) \neq P(Y)\]

La notación \(do(X)\) representa una intervención, no una observación.

2.4 Tipos de caminos en un DAG

2.4.1 Cadena (mediación)

Código
chain <- dagify(
  M ~ X,
  Y ~ M,
  coords = list(
    x = c(X = 0, M = 1, Y = 2),
    y = c(X = 0, M = 0, Y = 0)
  )
)

ggdag(chain) +
  theme_dag() +
  labs(title = "Cadena (Mediación)")
Figura 2.2: Cadena: X → M → Y

En una cadena, X causa Y a través de M. Si controlamos por M, bloqueamos el efecto.

2.4.2 Fork (confusión)

Código
fork <- dagify(
  X ~ C,
  Y ~ C,
  coords = list(
    x = c(X = 0, C = 1, Y = 2),
    y = c(X = 0, C = 1, Y = 0)
  )
)

ggdag(fork) +
  theme_dag() +
  labs(title = "Fork (Confusión)")
Figura 2.3: Fork: X ← C → Y

En un fork, C es causa común de X e Y. X e Y están asociadas pero X no causa Y.

2.4.3 Collider (colisionador)

Código
collider <- dagify(
  M ~ X + Y,
  coords = list(
    x = c(X = 0, M = 1, Y = 2),
    y = c(X = 0, M = -0.5, Y = 0)
  )
)

ggdag(collider) +
  theme_dag() +
  labs(title = "Collider")
Figura 2.4: Collider: X → M ← Y

En un collider, M es efecto de X e Y. X e Y no están asociadas, pero se vuelven asociadas si controlamos por M.

2.5 D-separación

La d-separación es un criterio para determinar si dos variables son independientes dado un conjunto de variables condicionantes.

ImportanteReglas de d-separación
  1. Cadenas y forks están bloqueados si condicionamos en el nodo intermedio
  2. Colliders están bloqueados por defecto, pero se abren si condicionamos en ellos (o sus descendientes)

2.5.1 Ejemplo

Código
example_dag <- dagify(
  Y ~ X + U,
  X ~ C,
  C ~ U,
  M ~ X + Y,
  exposure = "X",
  outcome = "Y",
  coords = list(
    x = c(X = 0, Y = 2, C = 0, U = 1, M = 1),
    y = c(X = 0, Y = 0, C = 1, U = 1, M = -1)
  )
)

ggdag_dseparated(example_dag, from = "X", to = "Y") +
  theme_dag() +
  labs(title = "¿X y Y son d-separadas?")
Figura 2.5: Ejemplo de d-separación

2.6 Identificación de confusores

Un confusor es una variable que:

  1. Causa (o está asociada con) la exposición
  2. Causa (o está asociada con) el resultado
  3. No está en el camino causal de X a Y
Código
library(dagitty)

g <- dagitty("dag {
  X -> Y
  C -> X
  C -> Y
}")

adjustmentSets(g, exposure = "X", outcome = "Y")
{ C }

2.7 Usando dagitty en R

El paquete dagitty permite:

  1. Definir DAGs
  2. Encontrar conjuntos de ajuste
  3. Verificar d-separación
library(dagitty)

# Definir DAG
mi_dag <- dagitty("dag {
  Tratamiento -> Resultado
  Edad -> Tratamiento
  Edad -> Resultado
  Sexo -> Resultado
}")

# Encontrar variables de ajuste
adjustmentSets(mi_dag, 
               exposure = "Tratamiento", 
               outcome = "Resultado")
{ Edad }

2.8 Aplicación: Ejemplo con datos

Consideremos un estudio sobre el efecto del ejercicio en la presión arterial:

# Simular datos
set.seed(42)
n <- 500

edad <- rnorm(n, 50, 10)
ejercicio <- 0.5 * edad + rnorm(n, 0, 5)  # Edad afecta ejercicio
presion <- 100 + 0.5 * edad - 0.3 * ejercicio + rnorm(n, 0, 10)

datos <- data.frame(edad, ejercicio, presion)

# Sin ajustar por edad (sesgado)
modelo_crudo <- lm(presion ~ ejercicio, data = datos)

# Ajustando por edad
modelo_ajustado <- lm(presion ~ ejercicio + edad, data = datos)

# Comparar
cat("Efecto crudo:", round(coef(modelo_crudo)[2], 3), "\n")
Efecto crudo: 0.208 
cat("Efecto ajustado:", round(coef(modelo_ajustado)[2], 3), "\n")
Efecto ajustado: -0.298 

2.9 Ejercicios

TipEjercicio 1

Construye un DAG para el siguiente escenario: Queremos estudiar el efecto del consumo de café en enfermedades cardíacas. Sabemos que el tabaquismo está asociado tanto con el consumo de café como con las enfermedades cardíacas.

TipEjercicio 2

Usando el paquete dagitty, determina el conjunto mínimo de variables que debes controlar para estimar el efecto causal.

2.10 Resumen

  • Los DAGs son herramientas gráficas para representar asunciones causales
  • Existen tres estructuras básicas: cadenas, forks y colliders
  • La d-separación nos ayuda a identificar qué variables controlar
  • Controlar por un collider introduce sesgo
  • El paquete dagitty facilita el trabajo con DAGs en R

Referencias