1. Introducción

La diabetes es una de las enfermedades crónicas más comunes y representa un reto importante para la salud pública.
Este informe busca explorar las características de los pacientes en la base de datos y analizar los factores asociados con la presencia de diabetes.

- Pregunta de investigación

¿Cuáles son las variables clínicas y demográficas que muestran mayor relación con el diagnóstico de diabetes?

2. Estadísticas descriptivas

Se procede a realizar una vista general del dataset en el cual se evidencia que hay 768 registros y 9 variables, entre las cuales se encuentran características clínicas como el número de embarazos, niveles de glucosa, presión arterial, grosor de la piel, insulina, índice de masa corporal (BMI), edad y el resultado del diagnóstico de diabetes (Outcome).

3. Estadísticas descriptivas y Tabla de frecuencias de Outcome de la variable ojetivo.

summary(datos)
##   Pregnancies        Glucose      BloodPressure    SkinThickness  
##  Min.   : 0.000   Min.   :  0.0   Min.   :  0.00   Min.   : 0.00  
##  1st Qu.: 1.000   1st Qu.: 99.0   1st Qu.: 62.00   1st Qu.: 0.00  
##  Median : 3.000   Median :117.0   Median : 72.00   Median :23.00  
##  Mean   : 3.845   Mean   :120.9   Mean   : 69.11   Mean   :20.54  
##  3rd Qu.: 6.000   3rd Qu.:140.2   3rd Qu.: 80.00   3rd Qu.:32.00  
##  Max.   :17.000   Max.   :199.0   Max.   :122.00   Max.   :99.00  
##     Insulin           BMI        DiabetesPedigreeFunction      Age       
##  Min.   :  0.0   Min.   : 0.00   Min.   :0.0780           Min.   :21.00  
##  1st Qu.:  0.0   1st Qu.:27.30   1st Qu.:0.2437           1st Qu.:24.00  
##  Median : 30.5   Median :32.00   Median :0.3725           Median :29.00  
##  Mean   : 79.8   Mean   :31.99   Mean   :0.4719           Mean   :33.24  
##  3rd Qu.:127.2   3rd Qu.:36.60   3rd Qu.:0.6262           3rd Qu.:41.00  
##  Max.   :846.0   Max.   :67.10   Max.   :2.4200           Max.   :81.00  
##     Outcome     
##  Min.   :0.000  
##  1st Qu.:0.000  
##  Median :0.000  
##  Mean   :0.349  
##  3rd Qu.:1.000  
##  Max.   :1.000
table(datos$Outcome)
## 
##   0   1 
## 500 268
prop.table(table(datos$Outcome))
## 
##         0         1 
## 0.6510417 0.3489583

4. Convertir varible categorica en factor

Se procede a convertir la variable Outcome en un factor con etiquetas más descriptivas para facilitar su interpretación en los análisis posteriores.

datos <- datos %>%
  mutate(Outcome = factor(Outcome, levels = c(0,1),
                          labels = c("No Diabetes", "Diabetes")))
datos %>%
  count(Outcome) %>%
  mutate(porcentaje = round(n / sum(n) * 100, 1))
##       Outcome   n porcentaje
## 1 No Diabetes 500       65.1
## 2    Diabetes 268       34.9

5. Analisis bivariado

Se realiza el siguiente analisis para determinar en cuáles variables difieren más los pacientes con y sin diabetes.

datos %>%
  group_by(Outcome) %>%
  summarise(
    Glucosa           = mean(Glucose, na.rm = TRUE),
    PresionArterial   = mean(BloodPressure, na.rm = TRUE),
    BMI               = mean(BMI, na.rm = TRUE),
    Insulina          = mean(Insulin, na.rm = TRUE),
    Edad              = mean(Age, na.rm = TRUE),
    Embarazos         = mean(Pregnancies, na.rm = TRUE),
    Pedigree          = mean(DiabetesPedigreeFunction, na.rm = TRUE)
  ) %>%
  pivot_longer(-Outcome, names_to = "Variable", values_to = "Media") %>%
  pivot_wider(names_from = Outcome, values_from = Media) %>%
  mutate(Diferencia_pct = round((Diabetes - `No Diabetes`) / `No Diabetes` * 100, 1))
## # A tibble: 7 × 4
##   Variable        `No Diabetes` Diabetes Diferencia_pct
##   <chr>                   <dbl>    <dbl>          <dbl>
## 1 Glucosa               110.     141.              28.4
## 2 PresionArterial        68.2     70.8              3.9
## 3 BMI                    30.3     35.1             16  
## 4 Insulina               68.8    100.              45.9
## 5 Edad                   31.2     37.1             18.8
## 6 Embarazos               3.30     4.87            47.5
## 7 Pedigree                0.430    0.550           28.1

En conjunto, las variables clínicas con mayor relación al diagnóstico de diabetes son Glucosa, Insulina y BMI, mientras que entre las variables demográficas destacan Edad y Embarazos. La Presión Arterial sería la variable de menor utilidad predictiva en este dataset.

6. Grafico de todas las variables

# Seleccionar variables numéricas y convertir a formato largo
datos %>%
  select(Outcome, Glucose, BloodPressure, BMI, Insulin, 
         Age, Pregnancies, DiabetesPedigreeFunction) %>%
  pivot_longer(-Outcome, names_to = "Variable", values_to = "Valor") %>%
  ggplot(aes(x = Outcome, y = Valor, fill = Outcome)) +
  geom_boxplot(alpha = 0.7, outlier.colour = "red", outlier.size = 1.5) +
  facet_wrap(~ Variable, scales = "free_y", ncol = 3) +
  scale_fill_manual(values = c("#2196F3", "#F44336")) +
  labs(
    title = "Distribución de variables clínicas y demográficas por diagnóstico de diabetes",
    x = "Diagnóstico",
    y = "Valor",
    fill = "Diagnóstico"
  ) +
  theme_minimal(base_size = 12) +
  theme(
    plot.title = element_text(face = "bold", hjust = 0.5),
    plot.subtitle = element_text(hjust = 0.5, color = "gray50"),
    legend.position = "bottom",
    strip.text = element_text(face = "bold")
  )

Glucose es visualmente la variable más discriminativa. Le siguen BMI y Age. BloodPressure confirma ser la variable de menor utilidad diagnóstica. Insulin muestra diferencias pero con mucha variabilidad, lo que puede afectar su peso en el modelo.

7. Distribución de variables principales

se evidencia graficamente que Glucose es visualmente la variable más discriminativa. Le siguen BMI y Age. BloodPressure confirma ser la variable de menor utilidad diagnóstica. Insulina muestra diferencias pero con mucha variabilidad, lo que puede afectar su peso en el modelo.

El BMI muestra una asociación clara y consistente con el diagnóstico de diabetes. Los pacientes diabéticos presentan en promedio un IMC en rango de obesidad, mientras que los no diabéticos se ubican en sobrepeso. La separación entre ambas distribuciones, aunque con cierto solapamiento, confirma al BMI como una variable clínicamente relevante para el diagnóstico de diabetes en esta muestra. Este hallazgo es coherente con la evidencia científica que establece la obesidad como uno de los principales factores de riesgo para diabetes tipo 2.

ggplot(datos, aes(x = Age, y = Glucose, color = factor(Outcome))) +
  geom_point(alpha = 0.6, size = 2) +
  geom_smooth(method = "lm", se = TRUE, linewidth = 1) +
  scale_color_manual(values = c("steelblue", "tomato"),
                     labels = c("No Diabetes", "Diabetes")) +
  labs(
    title = "Relación entre Edad y Glucosa según diagnóstico de diabetes",
    subtitle = "Cada punto representa un paciente | Línea de tendencia por grupo",
    x = "Edad (años)",
    y = "Glucosa (mg/dL)",
    color = "Diagnóstico"
  ) +
  theme_minimal(base_size = 13) +
  theme(
    plot.title = element_text(face = "bold", hjust = 0.5),
    plot.subtitle = element_text(hjust = 0.5, color = "gray50"),
    legend.position = "bottom"
  )

La glucosa mantiene una separación consistente entre grupos en todos los rangos de edad, siendo mayor en pacientes diabéticos a lo largo de toda la distribución etaria. Sin embargo, la brecha se amplía progresivamente con la edad, lo que sugiere que la combinación de edad avanzada + glucosa elevada es un indicador especialmente fuerte para el diagnóstico de diabetes. Este gráfico refuerza la necesidad de incluir ambas variables en el modelo predictivo.

8. Construcción del modelo de regresión.

# Convertir Outcome a numérico para la regresión
datos_modelo <- datos %>%
  mutate(Outcome = ifelse(Outcome == "Diabetes", 1, 0))

# Modelo de regresión logística con todas las variables
modelo <- glm(Outcome ~ Glucose + BloodPressure + BMI + 
                Insulin + Age + Pregnancies + 
                DiabetesPedigreeFunction,
              data = datos_modelo,
              family = binomial)

# Ver resultados
summary(modelo)
## 
## Call:
## glm(formula = Outcome ~ Glucose + BloodPressure + BMI + Insulin + 
##     Age + Pregnancies + DiabetesPedigreeFunction, family = binomial, 
##     data = datos_modelo)
## 
## Coefficients:
##                            Estimate Std. Error z value Pr(>|z|)    
## (Intercept)              -8.4051362  0.7167033 -11.727  < 2e-16 ***
## Glucose                   0.0351123  0.0036625   9.587  < 2e-16 ***
## BloodPressure            -0.0132136  0.0051537  -2.564 0.010350 *  
## BMI                       0.0900886  0.0144619   6.229 4.68e-10 ***
## Insulin                  -0.0011570  0.0008142  -1.421 0.155275    
## Age                       0.0147888  0.0092897   1.592 0.111393    
## Pregnancies               0.1231724  0.0320688   3.841 0.000123 ***
## DiabetesPedigreeFunction  0.9475954  0.2980063   3.180 0.001474 ** 
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## (Dispersion parameter for binomial family taken to be 1)
## 
##     Null deviance: 993.48  on 767  degrees of freedom
## Residual deviance: 723.45  on 760  degrees of freedom
## AIC: 739.45
## 
## Number of Fisher Scoring iterations: 5

9. Obtener Odds Ratios

# Odds Ratios con intervalos de confianza
exp(cbind(OR = coef(modelo), confint(modelo)))
## Waiting for profiling to be done...
##                                    OR        2.5 %       97.5 %
## (Intercept)              0.0002237153 5.217689e-05 0.0008687979
## Glucose                  1.0357359660 1.028526e+00 1.0434178749
## BloodPressure            0.9868733421 9.768200e-01 0.9968229716
## BMI                      1.0942712200 1.064449e+00 1.1266101512
## Insulin                  0.9988436337 9.972460e-01 1.0004466634
## Age                      1.0148987338 9.965014e-01 1.0335586474
## Pregnancies              1.1310794588 1.062820e+00 1.2054181681
## DiabetesPedigreeFunction 2.5794994240 1.447469e+00 4.6581035431

Resumen de tabla

La Insulina mostró diferencias grandes en el análisis bivariado (+45.9%) pero no es significativa en la regresión logística. Esto se explica porque su efecto está capturado por la Glucosa, con la que tiene alta correlación.

tidy(modelo, exponentiate = TRUE, conf.int = TRUE) %>%
  filter(term != "(Intercept)") %>%
  mutate(
    term = recode(term,
      "Glucose" = "Glucosa",
      "BloodPressure" = "Presión Arterial",
      "BMI" = "IMC (BMI)",
      "Insulin" = "Insulina",
      "Age" = "Edad",
      "Pregnancies" = "Embarazos",
      "DiabetesPedigreeFunction" = "Pedigree Diabético"
    ),
    significativo = ifelse(p.value < 0.05, "Significativo", "No significativo"),
    term = reorder(term, estimate)
  ) %>%
  ggplot(aes(x = estimate, y = term, color = significativo)) +
  geom_point(size = 4) +
  geom_errorbarh(aes(xmin = conf.low, xmax = conf.high), height = 0.3, linewidth = 0.8) +
  geom_vline(xintercept = 1, linetype = "dashed", color = "gray40", linewidth = 0.8) +
  scale_color_manual(values = c("Significativo" = "#E53935", "No significativo" = "#90A4AE")) +
  labs(
    title = "Odds Ratios de variables asociadas al diagnóstico de diabetes",
    subtitle = "Regresión logística multivariada | IC 95% | Línea punteada = OR de referencia (1.0)",
    x = "Odds Ratio (OR)",
    y = "Variable",
    color = "Significancia estadística"
  ) +
  theme_minimal(base_size = 13) +
  theme(
    plot.title = element_text(face = "bold", hjust = 0.5),
    plot.subtitle = element_text(hjust = 0.5, color = "gray50"),
    legend.position = "bottom"
  )
## Warning: `geom_errorbarh()` was deprecated in ggplot2 4.0.0.
## ℹ Please use the `orientation` argument of `geom_errorbar()` instead.
## This warning is displayed once per session.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
## `height` was translated to `width`.

El gráfico confirma visualmente que Pedigree Diabético, Embarazos, BMI y Glucosa son las variables con asociación estadísticamente significativa y positiva con el diagnóstico de diabetes. Pedigree Diabético destaca como el predictor más fuerte aunque con mayor incertidumbre, mientras que Glucosa y BMI ofrecen estimaciones más precisas y consistentes. Insulina y Edad no logran demostrar un efecto independiente en el modelo multivariado.

10. Generar la curva de ROC

# Obtener probabilidades predichas del modelo
datos_modelo$prob_pred <- predict(modelo, type = "response")

# Calcular la curva ROC
roc_obj <- roc(datos_modelo$Outcome, datos_modelo$prob_pred)
## Setting levels: control = 0, case = 1
## Setting direction: controls < cases
# Ver el AUC
auc(roc_obj)
## Area under the curve: 0.8396

Grafico de la curva de ROC

# Convertir a dataframe para ggplot
roc_df <- data.frame(
  Especificidad = 1 - roc_obj$specificities,
  Sensibilidad  = roc_obj$sensitivities
)

# Valor AUC para el gráfico
auc_valor <- round(auc(roc_obj), 3)

# Gráfico
ggplot(roc_df, aes(x = Especificidad, y = Sensibilidad)) +
  geom_line(color = "#E53935", linewidth = 1.2) +
  geom_abline(slope = 1, intercept = 0, linetype = "dashed", 
              color = "gray50", linewidth = 0.8) +
  geom_area(fill = "#E53935", alpha = 0.1) +
  annotate("text", x = 0.65, y = 0.25, 
           label = paste0("AUC = ", auc_valor),
           size = 5, fontface = "bold", color = "#E53935") +
  labs(
    title = "Curva ROC — Modelo de Regresión Logística",
    subtitle = "Diagnóstico de diabetes | Línea punteada = clasificador aleatorio",
    x = "1 - Especificidad (Tasa de Falsos Positivos)",
    y = "Sensibilidad (Tasa de Verdaderos Positivos)"
  ) +
  theme_minimal(base_size = 13) +
  theme(
    plot.title = element_text(face = "bold", hjust = 0.5),
    plot.subtitle = element_text(hjust = 0.5, color = "gray50")
  )

roc_obj <- roc(datos_modelo$Outcome, 
               datos_modelo$prob_pred,
               direction = "<")

Conclusión

Con un AUC de 0.84, el modelo de regresión logística construido con las variables Glucosa, BMI, Pedigree Diabético, Embarazos y Presión Arterial demuestra una buena capacidad diagnóstica para identificar pacientes con diabetes. Este resultado valida y respalda las conclusiones del análisis, confirmando que las variables identificadas como significativas no solo tienen asociación estadística, sino que en conjunto constituyen un modelo predictivo clínicamente útil.