Objetivo

En cada ejercicio (excepto el que usa base de datos), se presenta primero la solución matemática paso a paso, como se haría en un examen o pizarra, y después la implementación en R, para reforzar el razonamiento epidemiológico antes del uso del software.

Introducción

En este taller aprenderemos a calcular e interpretar las tres medidas fundamentales de la epidemiología:

  • Prevalencia (fotografía estática)
  • Incidencia acumulada (Riesgo) y Odds en cohorte cerrada
  • Tasa de incidencia (Densidad) en cohorte dinámica

El enfoque del taller es doble:

  1. Primero: razonamiento y solución matemática manual
  2. Segundo: implementación en R

1. Preparación del Entorno

Antes de empezar, cargamos las “herramientas” necesarias. Asegúrese de tener conexión a internet si es la primera vez que ejecuta estos comandos para descargar las librerías tidyverse, lubridate y epiR.

# --- PASO 0: INSTALACIÓN Y CARGA DE PAQUETES ---

# 1. Si no tiene los paquetes, R los instalará automáticamente con este código:
if(!require(tidyverse)) install.packages("tidyverse")
## Cargando paquete requerido: tidyverse
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.1.4     ✔ readr     2.1.5
## ✔ forcats   1.0.0     ✔ stringr   1.5.2
## ✔ ggplot2   4.0.0     ✔ tibble    3.3.0
## ✔ lubridate 1.9.4     ✔ tidyr     1.3.1
## ✔ purrr     1.1.0     
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
if(!require(lubridate)) install.packages("lubridate")
if(!require(epiR)) install.packages("epiR")
## Cargando paquete requerido: epiR
## Warning: package 'epiR' was built under R version 4.5.2
## Cargando paquete requerido: survival
## Package epiR 2.0.89 is loaded
## Type help(epi.about) for summary information
## Type browseVignettes(package = 'epiR') to learn how to use epiR for applied epidemiological analyses
if(!require(epitools)) install.packages("epitools", repos = "[http://cran.us.r-project.org](http://cran.us.r-project.org)")
## Cargando paquete requerido: epitools
## Warning: package 'epitools' was built under R version 4.5.2
## 
## Adjuntando el paquete: 'epitools'
## 
## The following object is masked from 'package:survival':
## 
##     ratetable
library(epitools)


# 2. Cargar las librerías en la memoria
library(tidyverse)  # Para manipulación de datos
library(lubridate)  # Para manejar fechas
library(epiR)       # Calculadora epidemiológica profesional
library(epitools)

print("✅ Entorno listo. Comencemos.")
## [1] "✅ Entorno listo. Comencemos."

2. Prevalencia (La fotografía)

Concepto: Es la proporción de la población que tiene el evento en un momento (Punto) o periodo específico. No mide riesgo, mide la carga de enfermedad en la comunidad.

La prevalencia puntual se define como:

\[ P = \frac{C}{N} \]

Donde:

    1. = número de casos existentes
    1. = población total

Ejercicio 1: Encuesta de diabetes

Imaginemos que realizamos una encuesta rápida a 20 pacientes en la sala de espera, de los cuales 5 resultaron ser diabéticos.

  • 0 = Sano
  • 1 = Enfermo (Caso prevalente)

Calcularemos la prevalencia puntual y su intervalo de confianza al 95%.

2.1. Solución Matemática Manual

Antes de programar, calculamos los indicadores básicos para entender la carga de la enfermedad.

A. Cálculo de la Prevalencia Puntual (\(P\))

La fórmula de la prevalencia es: \[P = \frac{Casos \ existentes (C)}{Población \ total (N)}\]

Sustituyendo los datos (\(C=5\), \(N=20\)): \[P = \frac{5}{20} = 0.25 \implies 25\%\]

B. Cálculo del Intervalo de Confianza (95%)

Utilizamos el método de Wald para la aproximación manual:

  1. Error Estándar (\(EE\)): \[EE = \sqrt{\frac{P \times (1 - P)}{n}} = \sqrt{\frac{0.25 \times 0.75}{20}} \approx 0.0968\]

  2. Límites del Intervalo (\(IC_{95\%}\)): \[IC = P \pm (1.96 \times EE)\] \[IC = 0.25 \pm (1.96 \times 0.0968) = 0.25 \pm 0.1897\] Resultado Manual: \(IC_{95\%} [0.0603 - 0.4397]\) o (6.0% - 44.0%).


2.2. Implementación en R

Una vez comprendida la base matemática, procedemos a la automatización. En epidemiología, no solo buscamos el dato puntual, sino la precisión del mismo expresada en sus intervalos de confianza. Note que R utiliza métodos exactos (como Wilson o Clopper-Pearson) que son más precisos que el cálculo manual en muestras pequeñas.

# --- 1. PREPARACIÓN ---
library(tidyverse)
library(epiR)

# --- 2. CARGA DE DATOS ---
datos_diabetes <- tibble(
  id = 1:20,
  estado = c(0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0)
)

# --- 3. PROCESAMIENTO ---
# Calculamos numerador (casos) y denominador (total)
num_casos <- sum(datos_diabetes$estado)
total_pacientes <- nrow(datos_diabetes)

# --- 4. CÁLCULO DE PREVALENCIA E IC 95% ---
# Para epi.conf, necesitamos una matriz con [casos, total]
matriz_datos <- matrix(c(num_casos, total_pacientes), nrow = 1, ncol = 2)

# Calculamos usando el método de proporción simple
# Por defecto, epi.conf utiliza el método de Wilson, ideal para muestras pequeñas
resultados <- epi.conf(matriz_datos, ctype = "prop.single")

# --- 5. RESULTADOS ---
print(paste("Casos encontrados:", num_casos))
## [1] "Casos encontrados: 5"
print(paste("Prevalencia:", resultados$est * 100, "%"))
## [1] "Prevalencia: 20 %"
print(paste("IC 95% (Inferior):", round(resultados$lower * 100, 2), "%"))
## [1] "IC 95% (Inferior): 8.86 %"
print(paste("IC 95% (Superior):", round(resultados$upper * 100, 2), "%"))
## [1] "IC 95% (Superior): 39.13 %"

3. Incidencia Acumulada (Riesgo) y Odds - Cohorte Cerrada

Concepto de Riesgo: La probabilidad de que ocurra un evento en un periodo determinado. El denominador es el total de personas en riesgo al inicio. Este cálculo asume que la población es fija (nadie entra, nadie sale y todos son seguidos por el mismo tiempo). Concepto de Odds: Es la razón entre la probabilidad de que el evento ocurra y la probabilidad de que no ocurra. El denominador son las personas que no tuvieron el evento.

Ejercicio 2: Incidencia Acumulada (Riesgo) y Odds

Escenario: Evaluamos los datos de una cohorte cerrada de 11,034 médicos que recibieron aspirina para prevenir infarto de miocardio (IAM). Tras el seguimiento, 139 desarrollaron un IAM, mientras que 10,895 permanecieron sanos.


3.1. Solución Matemática Manual

Datos del estudio: * Casos nuevos de IAM (\(a\)): 139 * Sujetos sanos al final del estudio (\(b\)): 10,895 * Población total en riesgo (\(n\)): 11,034 * Valor crítico \(Z_{0.95}\): 1.96


3.1.1. Incidencia Acumulada (IA) e Intervalo de Confianza

La IA es una proporción. Su intervalo de confianza se calcula mediante la aproximación normal.

A. Cálculo Puntual

\[IA = \frac{a}{n} = \frac{139}{11,034} = 0.01259 \implies 1.26\%\]

B. Error Estándar (EE)

\[EE(IA) = \sqrt{\frac{IA \times (1 - IA)}{n}} = \sqrt{\frac{0.01259 \times 0.98741}{11,034}} \approx 0.00106\]

C. Límites del IC 95%

\[IC = IA \pm (1.96 \times EE)\] \[IC = 0.01259 \pm (1.96 \times 0.00106) = 0.01259 \pm 0.00207\] Resultado: \(IC_{95\%} [1.05\% - 1.46\%]\)


3.1.2. Odds e Intervalo de Confianza

El Odds no es una proporción. Para su IC, debemos trabajar en escala logarítmica (\(\ln\)) para garantizar que los límites sean siempre positivos.

A. Cálculo Puntual

\[Odds = \frac{a}{b} = \frac{139}{10,895} = 0.01275\]

B. Error Estándar del Logaritmo del Odds

\[EE(\ln Odds) = \sqrt{\frac{1}{a} + \frac{1}{b}} = \sqrt{\frac{1}{139} + \frac{1}{10,895}} \approx 0.0853\]

C. Límites en Escala Logarítmica

  1. Punto central: \(\ln(0.01275) = -4.362\)
  2. Margen de error: \(1.96 \times 0.0853 = 0.167\)
  3. Límites logarítmicos: \([-4.362 - 0.167, -4.362 + 0.167] = [-4.529, -4.195]\)

D. Conversión a Escala Original (Antilogaritmo)

Utilizamos la función exponencial (\(e^x\)): * Límite Inferior: \(e^{-4.529} = 0.0107\) * Límite Superior: \(e^{-4.195} = 0.0150\)

Resultado: \(IC_{95\%} [0.0107 - 0.0150]\)


3.2. Comparativa Conceptual

Medida Denominador Interpretación
Riesgo (IA) Todos (Sanos + Enfermos) Probabilidad individual de enfermar.
Odds Solo los Sanos Ventaja o posibilidad de enfermar vs. no enfermar.

Nota: Observe que el límite superior del riesgo (1.46%) es menor que el del odds (1.50%). Esto ocurre porque el riesgo siempre está “contenido” por el total de la población, mientras que el odds puede crecer teóricamente hasta el infinito.


3.3. Implementación en R

Utilizaremos R para calcular ambos parámetros y sus intervalos de confianza, lo que nos permitirá ver qué tan similares son cuando el evento es “raro” (baja prevalencia/incidencia).

# 1. DATOS DE ENTRADA
casos_iam <- 139
total_medicos <- 11034
sanos_iam <- total_medicos - casos_iam

# 2. CÁLCULOS CON epiR
# Riesgo (Proporción): usamos casos y TOTAL
mat_riesgo <- matrix(c(casos_iam, total_medicos), nrow = 1, ncol = 2)
res_riesgo <- epi.conf(mat_riesgo, ctype = "prop.single")

# Odds (Razón): usamos casos y SANOS
mat_odds <- matrix(c(casos_iam, sanos_iam), nrow = 1, ncol = 2)
res_odds <- epi.conf(mat_odds, ctype = "odds")

# 3. IMPRESIÓN DE RESULTADOS (Nombres corregidos)
cat("--- COMPARATIVA MATEMÁTICA ---\n")
## --- COMPARATIVA MATEMÁTICA ---
# Imprimimos Riesgo
cat("Incidencia Acumulada (Riesgo):", round(res_riesgo$est * 100, 3), "%\n")
## Incidencia Acumulada (Riesgo): 1.244 %
cat("IC 95% Riesgo: [", round(res_riesgo$lower * 100, 3), "% - ", 
    round(res_riesgo$upper * 100, 3), "% ]\n\n")
## IC 95% Riesgo: [ 1.055 % -  1.467 % ]
# Imprimimos Odds (Cambiado 'odds_val' por 'res_odds$est')
cat("Odds (Posibilidad):", round(res_odds$est, 5), "\n")
## Odds (Posibilidad): 0.01276
cat("IC 95% Odds: [", round(res_odds$lower, 5), "-", 
    round(res_odds$upper, 5), "]\n\n")
## IC 95% Odds: [ 0.01072 - 0.0149 ]
cat("Nota: Observe que cuando el evento es raro (<10%), el Riesgo y el Odds son casi idénticos.")
## Nota: Observe que cuando el evento es raro (<10%), el Riesgo y el Odds son casi idénticos.
# --- REFLEXIÓN PEDAGÓGICA ---
# Note que cuando el evento es raro (frecuencia < 10%), el Riesgo y el Odds
# son numéricamente muy similares. Sin embargo, conceptualmente son distintos:
# El riesgo divide entre 'todos', el odds divide entre 'los que no enfermaron'.

4. Tasa de Incidencia (Densidad) - Cohorte Dinámica

Concepto: La velocidad con la que aparecen nuevos casos. Aquí el denominador ya no es “personas”, sino Tiempo-Persona. Es la medida vital cuando hay pérdidas de seguimiento (datos censurados) o tiempos de ingreso variables.

Ejercicio 3: Cohorte Cardiología Rosales

Trabajaremos con una cohorte simulada de 50 pacientes post-infarto.

Cálculo de Tasa Calcularemos los años-persona exactos restando la fecha de ingreso de la fecha de último control.

# --- EJERCICIO 3: CÁLCULO DE TASA DE INCIDENCIA ---

# 1. Cargar los datos
# Nota: Asegúrate de que el archivo csv esté en la carpeta usada como directorio de trabajo (Working Directory).
datos_cardio <- read_csv("cohorte_cardiologia_rosales.csv")
## Rows: 50 Columns: 4
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## dbl  (2): id, evento_infarto
## date (2): fecha_ingreso, fecha_ultimo_control
## 
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
# 2. Paso Crítico: Construir la variable Tiempo (Años-Persona)
# Usamos lubridate para restar fechas y convertir a años
datos_cardio <- datos_cardio %>%
  mutate(
    dias_riesgo = as.numeric(fecha_ultimo_control - fecha_ingreso),
    anios_riesgo = dias_riesgo / 365.25
  )

# Veamos los primeros 5 pacientes para entender qué hicimos
print(head(datos_cardio))
## # A tibble: 6 × 6
##      id fecha_ingreso fecha_ultimo_control evento_infarto dias_riesgo
##   <dbl> <date>        <date>                        <dbl>       <dbl>
## 1     1 2021-07-31    2021-12-20                        0         142
## 2     2 2021-07-02    2022-11-06                        1         492
## 3     3 2021-07-10    2023-07-26                        0         746
## 4     4 2021-11-30    2024-01-04                        0         765
## 5     5 2020-09-11    2022-02-05                        0         512
## 6     6 2021-09-12    2023-07-08                        0         664
## # ℹ 1 more variable: anios_riesgo <dbl>
# 3. Sumar el Numerador (Eventos) y el Denominador (Tiempo)
total_eventos <- sum(datos_cardio$evento_infarto)
total_tiempo_anios <- sum(datos_cardio$anios_riesgo)
total_pacientes <- nrow(datos_cardio)

print(paste("Total Eventos (Numerador):", total_eventos))
## [1] "Total Eventos (Numerador): 14"
print(paste("Total Años-Persona (Denominador):", round(total_tiempo_anios, 2)))
## [1] "Total Años-Persona (Denominador): 65.26"
# 4. Cálculo de la Tasa de Incidencia (TI)
# Fórmula: Eventos / Tiempo-Persona Total
tasa_incidencia <- total_eventos / total_tiempo_anios

print(paste("Tasa de Incidencia:", round(tasa_incidencia, 4), "eventos por año-persona"))
## [1] "Tasa de Incidencia: 0.2145 eventos por año-persona"
print(paste("Interpretación: Ocurren", round(tasa_incidencia * 100, 1), 
            "infartos por cada 100 años-persona de seguimiento."))
## [1] "Interpretación: Ocurren 21.5 infartos por cada 100 años-persona de seguimiento."
# 5. COMPARACIÓN: ¿Qué pasaría si usamos la fórmula incorrecta (Riesgo)?
# (El error ingenuo de dividir entre el N inicial)
riesgo_ingenuo <- total_eventos / total_pacientes

print("--- MOMENTO DE REFLEXIÓN ---")
## [1] "--- MOMENTO DE REFLEXIÓN ---"
print(paste("Cálculo Incorrecto (Riesgo Ingenuo):", riesgo_ingenuo * 100, "%"))
## [1] "Cálculo Incorrecto (Riesgo Ingenuo): 28 %"
print(paste("Cálculo Correcto (Tasa x 100 años-persona):", round(tasa_incidencia * 100, 1)))
## [1] "Cálculo Correcto (Tasa x 100 años-persona): 21.5"
# Note la diferencia. En cohortes dinámicas, el riesgo ingenuo suele fallar.

IMPORTANTE: No es que esperemos 100 años para ver los 25 infartos. Es que si juntamos el tiempo de todos los pacientes, al acumular 100 años-persona, esperaríamos ver esa cantidad de eventos.


5. Relación entre Prevalencia e Incidencia (\(P \approx I \times D\))

Concepto: Imagine un lavabo (o una bañera).

  • El grifo que vierte agua es la Incidencia (\(I\)): casos nuevos.
  • El nivel de agua estancada es la Prevalencia (\(P\)): casos existentes.
  • El desagüe es la salida (Cura o Muerte). Cuanto más pequeño es el desagüe, más tiempo permanece el agua (Duración, \(D\)).
Relación Prevalencia e Incidencia
Relación Prevalencia e Incidencia

Nota: La imagen superior ilustra cómo la duración de la enfermedad actúa como un factor multiplicador de la carga de enfermedad en el hospital.

La Fórmula de Oro: En una población estable y para enfermedades con prevalencia baja, la relación matemática es:

\[ Prevalencia \approx Incidencia \times Duración \]

Ejercicio 4: La Paradoja de Salud Pública

5.1.Resolución Manual

En este ejercicio aplicaremos la Fórmula de Oro de la epidemiología para entender por qué la carga hospitalaria no siempre depende de qué tan “contagiosa” es una enfermedad, sino de cuánto tiempo permanecen los pacientes enfermos.

1. Definición de la Fórmula

En una población estable, la relación entre Prevalencia (\(P\)), Incidencia (\(I\)) y Duración (\(D\)) es:

\[P \approx I \times D\]


2. Escenario A: Gripe (Alta Incidencia, Baja Duración)

La gripe se propaga rápidamente, pero el cuerpo la elimina en pocos días.

  • Incidencia (\(I\)): \(0.20\) (20% de la población se infecta al año).
  • Duración (\(D\)): \(1/52\) años (Aproximadamente 1 semana).

Cálculo de Prevalencia: \[P_{gripe} = 0.20 \times \left(\frac{1}{52}\right) = 0.0038\] Resultado: \(0.38\%\) de prevalencia puntual.


3. Escenario B: Diabetes (Baja Incidencia, Alta Duración)

La diabetes tiene pocos casos nuevos comparada con la gripe, pero es una condición de por vida.

  • Incidencia (\(I\)): \(0.01\) (Solo el 1% de la población desarrolla diabetes al año).
  • Duración (\(D\)): \(25\) años (Promedio de vida con la enfermedad).

Cálculo de Prevalencia: \[P_{diabetes} = 0.01 \times 25 = 0.25\] Resultado: \(25\%\) de prevalencia puntual.


4. Conclusión Pedagógica: La Paradoja

A pesar de que la Gripe es 20 veces más frecuente en términos de casos nuevos (incidencia), la Diabetes genera una carga hospitalaria 65 veces mayor en un momento dado.

Moraleja para el epidemiólogo: 1. Si quieres medir el éxito de un tratamiento que prolonga la vida (aumenta \(D\)), verás que la Prevalencia sube. ¡Eso es una buena noticia clínica aunque el número parezca mayor! 2. Si quieres medir el éxito de una vacuna (baja \(I\)), verás que tanto la incidencia como la prevalencia bajan.

5.2. Solución usando R

# --- EJERCICIO 4: SIMULACIÓN P = I x D ---

# 1. Definimos las variables
# Incidencia anual (casos por persona-año)
incidencia_gripe <- 0.20     # 20% de riesgo anual (Muy alto)
incidencia_diabetes <- 0.01  # 1% de riesgo anual (Bajo)

# Duración de la enfermedad (en años)
# Gripe: dura 1 semana (1/52 de un año)
duracion_gripe <- 1 / 52     
# Diabetes: dura 25 años promedio
duracion_diabetes <- 25      

# 2. Calculamos la Prevalencia estimada (P = I * D)
prevalencia_gripe <- incidencia_gripe * duracion_gripe
prevalencia_diabetes <- incidencia_diabetes * duracion_diabetes

# 3. Resultados
print(paste("Prevalencia Gripe:", round(prevalencia_gripe * 100, 2), "%"))
## [1] "Prevalencia Gripe: 0.38 %"
print(paste("Prevalencia Diabetes:", round(prevalencia_diabetes * 100, 2), "%"))
## [1] "Prevalencia Diabetes: 25 %"
# --- REFLEXIÓN CLÍNICA ---
# Observe los resultados:
# La Gripe tiene una incidencia 20 VECES MAYOR que la Diabetes.
# Sin embargo, la Diabetes tiene una carga (Prevalencia) 
# ~65 VECES MAYOR que la Gripe.

# 4. Escenario: ¿Qué pasa si mejoramos el tratamiento de la Diabetes?
# El nuevo medicamento NO cura, pero evita que el paciente muera rápido.
# Esto aumenta la Duración (D).

nueva_duracion <- 35 # Ahora viven 35 años con la enfermedad (antes 25)

nueva_prevalencia <- incidencia_diabetes * nueva_duracion

print(paste("Prevalencia tras 'mejorar' el tratamiento:", 
            round(nueva_prevalencia * 100, 2), "%"))
## [1] "Prevalencia tras 'mejorar' el tratamiento: 35 %"
# Conclusión automática
if(nueva_prevalencia > prevalencia_diabetes) {
  print("CONCLUSIÓN PARADÓJICA: ¡El éxito médico aumentó la prevalencia!")
  print("Recordatorio: No confunda aumento de prevalencia con fracaso del programa de prevención.")
}
## [1] "CONCLUSIÓN PARADÓJICA: ¡El éxito médico aumentó la prevalencia!"
## [1] "Recordatorio: No confunda aumento de prevalencia con fracaso del programa de prevención."

Hoja de Trucos: Medidas de Frecuencia en Epidemiología

Medida Pregunta que responde Denominador (Fondo de la fracción) Unidad de Medida Característica Clave
Prevalencia ¿Qué tan frecuente es la enfermedad hoy? Población total (\(N\)) Porcentaje o proporción Es una fotografía del momento actual.
Incidencia Acumulada ¿Qué riesgo tiene una persona de enfermar? Población sana al inicio Proporción (0 a 1) Mide la probabilidad en una cohorte cerrada.
Tasa de Incidencia ¿Qué tan rápido aparecen los casos? Tiempo-Persona total (\(\sum tiempo\)) Casos por unidad de tiempo Mide la velocidad de aparición.
Odds ¿Cuál es la posibilidad a favor vs. en contra? Sujetos que NO tuvieron el evento Razón (Ratio) Es la base para el Odds Ratio y la Regresión Logística.
P \(\approx\) I \(\times\) D ¿Cómo se relacionan? N/A Variable Útil para estimar la carga hospitalaria.

Tips para el examen:

  • Riesgo vs. Tasa: Si el grupo de estudio tiene muchas pérdidas (gente que se va o fallece por otra causa), la Tasa es más honesta que el Riesgo.
  • Riesgo vs. Odds: Si la enfermedad es “rara” (menos del 10% de la población la tiene), el Riesgo y el Odds serán casi idénticos.
  • P = I x D: Si un medicamento prolonga la vida del paciente pero no lo cura, la Prevalencia subirá (porque el agua se queda más tiempo en la bañera).

Fin del Tutorial.

Guarde su script como Practica_Semana3_NombreApellido.R