Este documento introduce de forma concisa las medidas de asociación más usadas en epidemiología aplicadas a dos diseños distintos:
En el estudio de casos y controles se estima la Razón de Odds
(OR), que aproxima la Razón de Riesgos (RR) si
la enfermedad es rara.
En el ensayo vacunal se calculan RR, Eficacia
Vacunal (VE), Diferencia de Riesgos (RD) y
Número Necesario a Vacunar (NNV).
NOTA terminológica: aquí “odds” se traduce como “razón de probabilidades” (probabilidad/(1−probabilidad)).
Para un evento (caso) y una exposición (p.ej. tabaquismo) en una tabla 2×2:
| Caso | No caso | |
|---|---|---|
| Expuestos | a | b |
| No expuestos | c | d |
Total \[N = a + b + c + d\].
Medidas básicas:
Intervalos de confianza (IC 95%) aproximados:
En un estudio de casos y controles no se estiman riesgos absolutos poblacionales (el número de casos y controles está fijado por diseño), pero el OR es interpretable como estimador del RR si la enfermedad es rara.
Estas funciones implementan los cálculos necesarios para los dos ejemplos.
# Función para cálculos básicos en 2x2 (riesgos observables)
calc_2x2_measures <- function(a, b, c, d, conf.level = 0.95) {
Re <- a / (a + b)
Ru <- c / (c + d)
RR <- Re / Ru
RD <- Re - Ru
OR <- (a * d) / (b * c)
z <- qnorm((1 + conf.level)/2)
se_logOR <- sqrt(1/a + 1/b + 1/c + 1/d)
CI_OR <- exp(log(OR) + c(-1, 1) * z * se_logOR)
se_logRR <- sqrt(1/a - 1/(a + b) + 1/c - 1/(c + d))
CI_RR <- exp(log(RR) + c(-1, 1) * z * se_logRR)
se_RD <- sqrt( (Re * (1 - Re))/(a + b) + (Ru * (1 - Ru))/(c + d) )
CI_RD <- RD + c(-1, 1) * z * se_RD
list(
a = a, b = b, c = c, d = d,
Riesgo_expuestos = Re,
Riesgo_no_expuestos = Ru,
RR = RR, IC95_RR = CI_RR,
RD = RD, IC95_RD = CI_RD,
OR = OR, IC95_OR = CI_OR
)
}
# Función para métricas de ensayo vacunal
calc_vaccine_metrics <- function(casos_vac, n_vac, casos_ctrl, n_ctrl, conf.level = 0.95){
Re <- casos_vac / n_vac
Ru <- casos_ctrl / n_ctrl
RR <- Re / Ru
VE <- 1 - RR
RD <- Re - Ru
NNV <- 1 / abs(RD)
z <- qnorm((1 + conf.level)/2)
se_logRR <- sqrt(1/casos_vac - 1/n_vac + 1/casos_ctrl - 1/n_ctrl)
CI_RR <- exp(log(RR) + c(-1, 1) * z * se_logRR)
se_RD <- sqrt( (Re*(1 - Re))/n_vac + (Ru*(1 - Ru))/n_ctrl )
CI_RD <- RD + c(-1, 1) * z * se_RD
list(
Riesgo_vac = Re, Riesgo_ctrl = Ru,
RR = RR, IC95_RR = CI_RR,
VE = VE,
RD = RD, IC95_RD = CI_RD,
NNV = NNV
)
}
Datos simplificados (varones) similares a los de Doll & Hill (valores ilustrativos):
| Cáncer pulmón | No cáncer | |
|---|---|---|
| Fumadores | 647 | 622 |
| No fumadores | 2 | 27 |
a <- 647; b <- 622; c <- 2; d <- 27
res_cancer <- calc_2x2_measures(a, b, c, d)
res_cancer
## $a
## [1] 647
##
## $b
## [1] 622
##
## $c
## [1] 2
##
## $d
## [1] 27
##
## $Riesgo_expuestos
## [1] 0.5098503
##
## $Riesgo_no_expuestos
## [1] 0.06896552
##
## $RR
## [1] 7.392829
##
## $IC95_RR
## [1] 1.938981 28.186934
##
## $RD
## [1] 0.4408848
##
## $IC95_RD
## [1] 0.3446459 0.5371236
##
## $OR
## [1] 14.0426
##
## $IC95_OR
## [1] 3.325329 59.300825
# crear una tabla gt con los valores de RR, RD OR con sus IC95%
library(gt)
tabla_cancer <- data.frame(
Medida = c("RR", "RD", "OR"),
Estimador = c(res_cancer$RR, res_cancer$RD, res_cancer$OR),
IC95_Lower = c(res_cancer$IC95_RR[1], res_cancer$IC95_RD[1], res_cancer$IC95_OR[1]),
IC95_Upper = c(res_cancer$IC95_RR[2], res_cancer$IC95_RD[2], res_cancer$IC95_OR[2])
)
tabla_cancer %>%
gt() %>%
fmt_number(
columns = vars(Estimador, IC95_Lower, IC95_Upper),
decimals = 3
) %>%
cols_label(
Medida = "Medida",
Estimador = "Estimador",
IC95_Lower = "IC 95% Lower",
IC95_Upper = "IC 95% Upper"
) %>%
tab_header(
title = "Medidas de Asociación: Cáncer de Pulmón y Tabaquismo"
)
| Medidas de Asociación: Cáncer de Pulmón y Tabaquismo | |||
| Medida | Estimador | IC 95% Lower | IC 95% Upper |
|---|---|---|---|
| RR | 7.393 | 1.939 | 28.187 |
| RD | 0.441 | 0.345 | 0.537 |
| OR | 14.043 | 3.325 | 59.301 |
Vamos a analizar el caso de la vacuna Salk contra la poliomielitis (1950s) en un ensayo aleatorizado:
Datos (simplificados del ensayo histórico):
| Grupo | Casos poliomielitis | Total |
|---|---|---|
| Vacunados | 33 | 200,745 |
| No vacunados | 115 | 201,229 |
casos_vac <- 33; n_vac <- 200745
casos_ctrl <- 115; n_ctrl <- 201229
res_vac <- calc_vaccine_metrics(casos_vac, n_vac, casos_ctrl, n_ctrl)
res_vac
## $Riesgo_vac
## [1] 0.0001643877
##
## $Riesgo_ctrl
## [1] 0.0005714882
##
## $RR
## [1] 0.2876484
##
## $IC95_RR
## [1] 0.1953383 0.4235810
##
## $VE
## [1] 0.7123516
##
## $RD
## [1] -0.0004071005
##
## $IC95_RD
## [1] -0.0005256277 -0.0002885734
##
## $NNV
## [1] 2456.396
# crear una tabla gt con los valores de RR, VE, RD y NNV con sus IC95%
tabla_vac <- data.frame(
Medida = c("RR", "VE", "RD", "NNV"),
Estimador = c(res_vac$RR, res_vac$VE, res_vac$RD, res_vac$NNV),
IC95_Lower = c(res_vac$IC95_RR[1], NA, res_vac$IC95_RD[1], NA),
IC95_Upper = c(res_vac$IC95_RR[2], NA, res_vac$IC95_RD[2], NA)
)
tabla_vac %>%
gt() %>%
fmt_number(
columns = vars(Estimador, IC95_Lower, IC95_Upper),
decimals = 3
) %>%
cols_label(
Medida = "Medida",
Estimador = "Estimador",
IC95_Lower = "IC 95% Lower",
IC95_Upper = "IC 95% Upper"
) %>%
tab_header(
title = "Medidas de Asociación: Ensayo Vacunal Salk"
)
| Medidas de Asociación: Ensayo Vacunal Salk | |||
| Medida | Estimador | IC 95% Lower | IC 95% Upper |
|---|---|---|---|
| RR | 0.288 | 0.195 | 0.424 |
| VE | 0.712 | NA | NA |
| RD | 0.000 | −0.001 | 0.000 |
| NNV | 2,456.396 | NA | NA |
| Aspecto | Casos y controles (Cáncer) | Ensayo vacunal (Salk) |
|---|---|---|
| Medida primaria | OR (aprox RR si raro) | RR, VE |
| Riesgos absolutos | No (por diseño) | Sí |
| RD | No interpretable directo | Sí (diferencia de riesgos) |
| NNV | No (sin riesgos) | Sí |
| Estabilidad estimador | Sensible a c muy pequeño | Alta (grandes muestras) |
| Interpretación clínica | Asociación | Efecto causal (si buen diseño) |
Doll, R. & Hill, A. B. (1950). Smoking and carcinoma of the lung. British Medical Journal (estudio fundacional sobre tabaquismo y cáncer de pulmón).
````