1. Introducción a la base de Datos:

Nombre del dataset: diabetic_data.csv
Número de instancias: 101,766
Número de variables: 47

1.1 contexto del dataset:

El conjunto de datos abarca diez años (1999–2008) de atención clínica en 130 hospitales y redes de prestación de servicios en EE. UU. Cada fila representa un registro hospitalario de pacientes diagnosticados con diabetes, que fueron sometidos a pruebas de laboratorio, tratamientos médicos y hospitalización por hasta 14 días.

El objetivo principal es determinar si un paciente fue readmitido dentro de los 30 días posteriores al alta médica. Este problema es relevante debido a que:

  • Muchos pacientes diabéticos no reciben intervenciones preventivas adecuadas.
  • El manejo de la diabetes en entornos hospitalarios puede ser inconsistente, afectando el control glucémico.
  • La falta de atención adecuada puede aumentar la morbilidad, mortalidad y los costos hospitalarios debido a reingresos frecuentes.

1.2. Autoría y contexto:

  • Autoras: Guirlessa De la Hoz & Mariangel Mercado
  • Curso: Machine Learning
  • Fecha: Agosto de 2025

2. Descripción de Variables:

A continuación se describen las variables presentes en el dataset diabetic_data.csv, organizadas por categorías:


🔐 Variables de Identificación

Variable Tipo Descripción
encounter_id Numérica Identificador único del encuentro hospitalario (visita).
patient_nbr Numérica Identificador único del paciente.

👤 Datos Demográficos y de Ingreso

Variable Tipo Descripción
race Categórica Raza del paciente. Valores: Caucasian, Asian, African American, Hispanic, Other.
gender Categórica Género del paciente. Valores: male, female, unknown/invalid.
age Categórica Edad agrupada en intervalos de 10 años (ej. [50-60)).
weight Numérica/Categórica Peso del paciente (en libras). Muchos valores faltantes.
admission_type_id Categórica (codificada) Tipo de admisión (1=Emergency, 2=Urgent, 3=Elective, etc.).
discharge_disposition_id Categórica (codificada) Disposición al alta. Indica el destino del paciente al ser dado de alta.
admission_source_id Categórica (codificada) Fuente de admisión (referencia médica, urgencias, etc.).
time_in_hospital Numérica Días de estancia en el hospital.

🔬 Pruebas y Procedimientos

Variable Tipo Descripción
num_lab_procedures Numérica Número de pruebas de laboratorio realizadas.
num_procedures Numérica Número de procedimientos distintos realizados (excluye laboratorios).
num_medications Numérica Número de medicamentos diferentes administrados.
number_outpatient Numérica Número de visitas ambulatorias previas.
number_emergency Numérica Número de visitas a urgencias previas.
number_inpatient Numérica Número de ingresos hospitalarios previos.
number_diagnoses Numérica Número de diagnósticos registrados.

🏥 Diagnósticos Principales

Variable Tipo Descripción
diag_1 Categórica Diagnóstico principal (código ICD9, 3 dígitos).
diag_2 Categórica Diagnóstico secundario.
diag_3 Categórica Diagnóstico adicional.

💉 Resultados de Laboratorio

Variable Tipo Descripción
max_glu_serum Categórica Resultado máximo de glucosa en suero. Valores: >200, >300, normal, none.
A1Cresult Categórica Resultado de hemoglobina A1C. Valores: >8, >7, normal, none.

💊 Medicamentos Administrados

Cada una de las siguientes variables indica si el medicamento fue administrado y si hubo cambio de dosis.
Valores posibles: up, down, steady, no.

Variables:

metformin, repaglinide, nateglinide, chlorpropamide, glimepiride, acetohexamide, glipizide, glyburide, tolbutamide, pioglitazone, rosiglitazone, acarbose, miglitol, troglitazone, tolazamide, examide, citoglipton, insulin, glyburide-metformin, glipizide-metformin, glimepiride-pioglitazone, metformin-rosiglitazone, metformin-pioglitazone


⚙️ Control del Tratamiento

Variable Tipo Descripción
change Categórica Indica si hubo algún cambio en los medicamentos para la diabetes durante la estancia (change, no change).
diabetesMed Categórica Indica si se prescribió algún medicamento para la diabetes (yes, no).

🎯 Variable Objetivo

Variable Tipo Descripción
readmitted Categórica Indica si el paciente fue readmitido y cuándo. Valores: <30, >30, No.

3. Librerías y Cargue de los Datos:

Se importan todas las librerias a utilizar:

library(readr)
library(dplyr)
## 
## Adjuntando el paquete: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
library(ggplot2)
## Warning: package 'ggplot2' was built under R version 4.4.3
library(tidyr)
library(gridExtra)
## Warning: package 'gridExtra' was built under R version 4.4.3
## 
## Adjuntando el paquete: 'gridExtra'
## The following object is masked from 'package:dplyr':
## 
##     combine
library(dplyr)
library(pracma)
## Warning: package 'pracma' was built under R version 4.4.3
library(patchwork)
## Warning: package 'patchwork' was built under R version 4.4.3
library(forcats)
## Warning: package 'forcats' was built under R version 4.4.3
library(RColorBrewer)
library(GGally)
## Warning: package 'GGally' was built under R version 4.4.3

Se cargan los datos a analizar

df = read.csv("diabetic_data.csv")

4. Observación de los datos:

str(df)
## 'data.frame':    101766 obs. of  50 variables:
##  $ encounter_id            : int  2278392 149190 64410 500364 16680 35754 55842 63768 12522 15738 ...
##  $ patient_nbr             : int  8222157 55629189 86047875 82442376 42519267 82637451 84259809 114882984 48330783 63555939 ...
##  $ race                    : chr  "Caucasian" "Caucasian" "AfricanAmerican" "Caucasian" ...
##  $ gender                  : chr  "Female" "Female" "Female" "Male" ...
##  $ age                     : chr  "[0-10)" "[10-20)" "[20-30)" "[30-40)" ...
##  $ weight                  : chr  "?" "?" "?" "?" ...
##  $ admission_type_id       : int  6 1 1 1 1 2 3 1 2 3 ...
##  $ discharge_disposition_id: int  25 1 1 1 1 1 1 1 1 3 ...
##  $ admission_source_id     : int  1 7 7 7 7 2 2 7 4 4 ...
##  $ time_in_hospital        : int  1 3 2 2 1 3 4 5 13 12 ...
##  $ payer_code              : chr  "?" "?" "?" "?" ...
##  $ medical_specialty       : chr  "Pediatrics-Endocrinology" "?" "?" "?" ...
##  $ num_lab_procedures      : int  41 59 11 44 51 31 70 73 68 33 ...
##  $ num_procedures          : int  0 0 5 1 0 6 1 0 2 3 ...
##  $ num_medications         : int  1 18 13 16 8 16 21 12 28 18 ...
##  $ number_outpatient       : int  0 0 2 0 0 0 0 0 0 0 ...
##  $ number_emergency        : int  0 0 0 0 0 0 0 0 0 0 ...
##  $ number_inpatient        : int  0 0 1 0 0 0 0 0 0 0 ...
##  $ diag_1                  : chr  "250.83" "276" "648" "8" ...
##  $ diag_2                  : chr  "?" "250.01" "250" "250.43" ...
##  $ diag_3                  : chr  "?" "255" "V27" "403" ...
##  $ number_diagnoses        : int  1 9 6 7 5 9 7 8 8 8 ...
##  $ max_glu_serum           : chr  "None" "None" "None" "None" ...
##  $ A1Cresult               : chr  "None" "None" "None" "None" ...
##  $ metformin               : chr  "No" "No" "No" "No" ...
##  $ repaglinide             : chr  "No" "No" "No" "No" ...
##  $ nateglinide             : chr  "No" "No" "No" "No" ...
##  $ chlorpropamide          : chr  "No" "No" "No" "No" ...
##  $ glimepiride             : chr  "No" "No" "No" "No" ...
##  $ acetohexamide           : chr  "No" "No" "No" "No" ...
##  $ glipizide               : chr  "No" "No" "Steady" "No" ...
##  $ glyburide               : chr  "No" "No" "No" "No" ...
##  $ tolbutamide             : chr  "No" "No" "No" "No" ...
##  $ pioglitazone            : chr  "No" "No" "No" "No" ...
##  $ rosiglitazone           : chr  "No" "No" "No" "No" ...
##  $ acarbose                : chr  "No" "No" "No" "No" ...
##  $ miglitol                : chr  "No" "No" "No" "No" ...
##  $ troglitazone            : chr  "No" "No" "No" "No" ...
##  $ tolazamide              : chr  "No" "No" "No" "No" ...
##  $ examide                 : chr  "No" "No" "No" "No" ...
##  $ citoglipton             : chr  "No" "No" "No" "No" ...
##  $ insulin                 : chr  "No" "Up" "No" "Up" ...
##  $ glyburide.metformin     : chr  "No" "No" "No" "No" ...
##  $ glipizide.metformin     : chr  "No" "No" "No" "No" ...
##  $ glimepiride.pioglitazone: chr  "No" "No" "No" "No" ...
##  $ metformin.rosiglitazone : chr  "No" "No" "No" "No" ...
##  $ metformin.pioglitazone  : chr  "No" "No" "No" "No" ...
##  $ change                  : chr  "No" "Ch" "No" "Ch" ...
##  $ diabetesMed             : chr  "No" "Yes" "Yes" "Yes" ...
##  $ readmitted              : chr  "NO" ">30" "NO" "NO" ...
# Mostrar todas las columnas
options(dplyr.width = Inf)

# Primeras filas
df %>% head()
##   encounter_id patient_nbr            race gender     age weight
## 1      2278392     8222157       Caucasian Female  [0-10)      ?
## 2       149190    55629189       Caucasian Female [10-20)      ?
## 3        64410    86047875 AfricanAmerican Female [20-30)      ?
## 4       500364    82442376       Caucasian   Male [30-40)      ?
## 5        16680    42519267       Caucasian   Male [40-50)      ?
## 6        35754    82637451       Caucasian   Male [50-60)      ?
##   admission_type_id discharge_disposition_id admission_source_id
## 1                 6                       25                   1
## 2                 1                        1                   7
## 3                 1                        1                   7
## 4                 1                        1                   7
## 5                 1                        1                   7
## 6                 2                        1                   2
##   time_in_hospital payer_code        medical_specialty num_lab_procedures
## 1                1          ? Pediatrics-Endocrinology                 41
## 2                3          ?                        ?                 59
## 3                2          ?                        ?                 11
## 4                2          ?                        ?                 44
## 5                1          ?                        ?                 51
## 6                3          ?                        ?                 31
##   num_procedures num_medications number_outpatient number_emergency
## 1              0               1                 0                0
## 2              0              18                 0                0
## 3              5              13                 2                0
## 4              1              16                 0                0
## 5              0               8                 0                0
## 6              6              16                 0                0
##   number_inpatient diag_1 diag_2 diag_3 number_diagnoses max_glu_serum
## 1                0 250.83      ?      ?                1          None
## 2                0    276 250.01    255                9          None
## 3                1    648    250    V27                6          None
## 4                0      8 250.43    403                7          None
## 5                0    197    157    250                5          None
## 6                0    414    411    250                9          None
##   A1Cresult metformin repaglinide nateglinide chlorpropamide glimepiride
## 1      None        No          No          No             No          No
## 2      None        No          No          No             No          No
## 3      None        No          No          No             No          No
## 4      None        No          No          No             No          No
## 5      None        No          No          No             No          No
## 6      None        No          No          No             No          No
##   acetohexamide glipizide glyburide tolbutamide pioglitazone rosiglitazone
## 1            No        No        No          No           No            No
## 2            No        No        No          No           No            No
## 3            No    Steady        No          No           No            No
## 4            No        No        No          No           No            No
## 5            No    Steady        No          No           No            No
## 6            No        No        No          No           No            No
##   acarbose miglitol troglitazone tolazamide examide citoglipton insulin
## 1       No       No           No         No      No          No      No
## 2       No       No           No         No      No          No      Up
## 3       No       No           No         No      No          No      No
## 4       No       No           No         No      No          No      Up
## 5       No       No           No         No      No          No  Steady
## 6       No       No           No         No      No          No  Steady
##   glyburide.metformin glipizide.metformin glimepiride.pioglitazone
## 1                  No                  No                       No
## 2                  No                  No                       No
## 3                  No                  No                       No
## 4                  No                  No                       No
## 5                  No                  No                       No
## 6                  No                  No                       No
##   metformin.rosiglitazone metformin.pioglitazone change diabetesMed readmitted
## 1                      No                     No     No          No         NO
## 2                      No                     No     Ch         Yes        >30
## 3                      No                     No     No         Yes         NO
## 4                      No                     No     Ch         Yes         NO
## 5                      No                     No     Ch         Yes         NO
## 6                      No                     No     No         Yes        >30

4.1 Transformación de códigos ICD-9

Al observar los datos, nos llamaron la atención dos aspectos. El primero es la presencia de valores representados como “?” dentro del dataset, los cuales corresponden a valores faltantes que no han sido reconocidos como tal, pero que trataremos más adelante. El segundo se refiere a un caso particular en tres variables: diag_1, diag_2 y diag_3. Estas variables contienen códigos de diagnóstico en formato ICD-9 que, en su forma actual —principalmente números enteros— resultan poco interpretables para un análisis clínico o estadístico directo.

No obstante, al revisar el artículo de investigación “Impact of HbA1c Measurement on Hospital Readmission Rates: Analysis of 70,000 Clinical Database Patient Records”, identificamos una propuesta para agrupar estos códigos en categorías médicas más comprensibles (como enfermedades circulatorias, respiratorias, digestivas, entre otras).

Por consiguiente, decidimos llevar a cabo esta transformación, convirtiendo los códigos ICD-9 en categorías médicas más claras y relevantes para nuestro análisis de reingresos hospitalarios.

map_icd9 <- function(code) {
  if (is.na(code)) {
    return("Desconocido")
  }
  
  if (code == "?") {
    return("?")  # mantener el signo de interrogación
  }
  
  # Convertir a string
  code_str <- as.character(code)
  
  # Casos especiales tipo string
  if (startsWith(code_str, "V") || startsWith(code_str, "E")) {
    return("Causas externas")
  }
  
  # Intentar convertir a número
  code_num <- suppressWarnings(as.numeric(code_str))
  
  if (is.na(code_num)) {
    return("Otro")
  }
  
  # Comparaciones numéricas
  if ((code_num >= 390 && code_num <= 459) || code_num == 785) {
    return("Circulatorio")
  } else if ((code_num >= 460 && code_num <= 519) || code_num == 786) {
    return("Respiratorio")
  } else if ((code_num >= 520 && code_num <= 579) || code_num == 787) {
    return("Digestivo")
  } else if (code_num >= 250 && code_num < 251) {  
    return("Diabetes")
  } else if (code_num >= 800 && code_num <= 999) {
    return("Herida")
  } else if (code_num >= 710 && code_num <= 739) {
    return("Musculoesquelético")
  } else if ((code_num >= 580 && code_num <= 629) || code_num == 788) {
    return("Genitourinario")
  } else if (code_num >= 140 && code_num <= 239) {
    return("Neoplasmas")
  } else if ((code_num >= 780 && code_num <= 784) || (code_num >= 790 && code_num <= 799)) {
    return("Síntomas mal definidos")
  } else if ((code_num >= 240 && code_num <= 279) && !(code_num >= 250 && code_num < 251)) {
    return("Endocrino y metabolismo (sin diabetes)")
  } else if ((code_num >= 680 && code_num <= 709) || code_num == 782) {
    return("Piel y tejido subcutáneo")
  } else if (code_num >= 1 && code_num <= 139) {
    return("Infecciosas y parasitarias")
  } else if (code_num >= 290 && code_num <= 319) {
    return("Trastornos mentales")
  } else if (code_num >= 280 && code_num <= 289) {
    return("Sangre y órganos hematopoyéticos")
  } else if (code_num >= 320 && code_num <= 359) {
    return("Sistema nervioso")
  } else if (code_num >= 630 && code_num <= 679) {
    return("Embarazo y puerperio")
  } else if (code_num >= 360 && code_num <= 389) {
    return("Órganos de los sentidos")
  } else if (code_num >= 740 && code_num <= 759) {
    return("Anomalías congénitas")
  } else {
    return("Otro")
  }
}

Se creo la función map_icd9 con el fin de hacer el cambio de codigo a etiqueta en las variables de diagnosticos.

# Transformar las columnas diag_1, diag_2 y diag_3
df$diag_1 <- sapply(df$diag_1, map_icd9)
df$diag_2 <- sapply(df$diag_2, map_icd9)
df$diag_3 <- sapply(df$diag_3, map_icd9)

# Mostrar las primeras filas
head(df)
##   encounter_id patient_nbr            race gender     age weight
## 1      2278392     8222157       Caucasian Female  [0-10)      ?
## 2       149190    55629189       Caucasian Female [10-20)      ?
## 3        64410    86047875 AfricanAmerican Female [20-30)      ?
## 4       500364    82442376       Caucasian   Male [30-40)      ?
## 5        16680    42519267       Caucasian   Male [40-50)      ?
## 6        35754    82637451       Caucasian   Male [50-60)      ?
##   admission_type_id discharge_disposition_id admission_source_id
## 1                 6                       25                   1
## 2                 1                        1                   7
## 3                 1                        1                   7
## 4                 1                        1                   7
## 5                 1                        1                   7
## 6                 2                        1                   2
##   time_in_hospital payer_code        medical_specialty num_lab_procedures
## 1                1          ? Pediatrics-Endocrinology                 41
## 2                3          ?                        ?                 59
## 3                2          ?                        ?                 11
## 4                2          ?                        ?                 44
## 5                1          ?                        ?                 51
## 6                3          ?                        ?                 31
##   num_procedures num_medications number_outpatient number_emergency
## 1              0               1                 0                0
## 2              0              18                 0                0
## 3              5              13                 2                0
## 4              1              16                 0                0
## 5              0               8                 0                0
## 6              6              16                 0                0
##   number_inpatient                                 diag_1       diag_2
## 1                0                               Diabetes            ?
## 2                0 Endocrino y metabolismo (sin diabetes)     Diabetes
## 3                1                   Embarazo y puerperio     Diabetes
## 4                0             Infecciosas y parasitarias     Diabetes
## 5                0                             Neoplasmas   Neoplasmas
## 6                0                           Circulatorio Circulatorio
##                                   diag_3 number_diagnoses max_glu_serum
## 1                                      ?                1          None
## 2 Endocrino y metabolismo (sin diabetes)                9          None
## 3                        Causas externas                6          None
## 4                           Circulatorio                7          None
## 5                               Diabetes                5          None
## 6                               Diabetes                9          None
##   A1Cresult metformin repaglinide nateglinide chlorpropamide glimepiride
## 1      None        No          No          No             No          No
## 2      None        No          No          No             No          No
## 3      None        No          No          No             No          No
## 4      None        No          No          No             No          No
## 5      None        No          No          No             No          No
## 6      None        No          No          No             No          No
##   acetohexamide glipizide glyburide tolbutamide pioglitazone rosiglitazone
## 1            No        No        No          No           No            No
## 2            No        No        No          No           No            No
## 3            No    Steady        No          No           No            No
## 4            No        No        No          No           No            No
## 5            No    Steady        No          No           No            No
## 6            No        No        No          No           No            No
##   acarbose miglitol troglitazone tolazamide examide citoglipton insulin
## 1       No       No           No         No      No          No      No
## 2       No       No           No         No      No          No      Up
## 3       No       No           No         No      No          No      No
## 4       No       No           No         No      No          No      Up
## 5       No       No           No         No      No          No  Steady
## 6       No       No           No         No      No          No  Steady
##   glyburide.metformin glipizide.metformin glimepiride.pioglitazone
## 1                  No                  No                       No
## 2                  No                  No                       No
## 3                  No                  No                       No
## 4                  No                  No                       No
## 5                  No                  No                       No
## 6                  No                  No                       No
##   metformin.rosiglitazone metformin.pioglitazone change diabetesMed readmitted
## 1                      No                     No     No          No         NO
## 2                      No                     No     Ch         Yes        >30
## 3                      No                     No     No         Yes         NO
## 4                      No                     No     Ch         Yes         NO
## 5                      No                     No     Ch         Yes         NO
## 6                      No                     No     No         Yes        >30

Observe como efectivamente hemos conseguido etiquetas interpretables en las variables de diagnostico.

5. Limpieza de los Datos:

5.1 Análisis de Valores Faltantes:

En primera instancia, recurrimos a hacer un mapa de calor y una tabla de valores faltantes para una primera inspección.

df_missing <- df %>%
  mutate(across(everything(), as.character)) %>%  # convertir todo a texto
  mutate(row = row_number()) %>%
  pivot_longer(cols = -row, names_to = "variable", values_to = "value") %>%
  mutate(missing = is.na(value) | value == "NA")  # marcar NA reales y "NA" texto

ggplot(df_missing, aes(x = variable, y = row, fill = missing)) +
  geom_tile() +
  scale_fill_manual(values = c("FALSE" = "skyblue", "TRUE" = "purple")) +
  theme_minimal() +
  theme(axis.text.y = element_blank(),
        axis.ticks.y = element_blank(),
        axis.text.x = element_text(angle = 90)) +
  ggtitle("Mapa de calor de valores faltantes")

Notamos que, a primera vista, nuestros datos no presentan valores faltantes; sin embargo, durante la revisión observamos que algunas variables contienen valores representados como “?”, los cuales deben ser considerados como NA. Por lo que, el paso a seguir es reemplazar manualmente estos símbolos para permitir un tratamiento adecuado de los valores ausentes en etapas posteriores del análisis.

# Reemplazar '?' por NA
df[df == "?"] <- NA

# Preparar datos para el mapa de calor
df_missing <- df %>%
  mutate(row = row_number()) %>%
  pivot_longer(cols = -row,
               names_to = "variable",
               values_to = "value",
               values_transform = as.character) %>%
  mutate(missing = is.na(value))

# Graficar mapa de calor estilo seaborn
ggplot(df_missing, aes(x = variable, y = row, fill = missing)) +
  geom_tile() +
  scale_fill_manual(values = c("FALSE" = "skyblue", "TRUE" = "purple")) +
  theme_minimal() +
  theme(axis.text.y = element_blank(),
        axis.ticks.y = element_blank(),
        axis.text.x = element_text(angle = 90)) +
  ggtitle("Mapa de calor de valores faltantes")

tabla_faltantes <- data.frame(
  "Valores faltantes" = colSums(is.na(df)),
  "Porcentaje (%)" = colMeans(is.na(df)) * 100,
  check.names = FALSE   # <-- evita que R cambie los nombres
) %>%
  filter(`Valores faltantes` > 0) %>%         # usar comillas invertidas
  arrange(desc(`Porcentaje (%)`))             # usar comillas invertidas

tabla_faltantes
##                   Valores faltantes Porcentaje (%)
## weight                        98569    96.85847926
## medical_specialty             49949    49.08220820
## payer_code                    40256    39.55741603
## race                           2273     2.23355541
## diag_3                         1423     1.39830592
## diag_2                          358     0.35178743
## diag_1                           21     0.02063558

Observemos que la variable weight presenta un 96.86% de datos faltantes. Dado que este porcentaje es extremadamente alto, cualquier técnica de imputación resultaría ineficiente y podría introducir sesgos significativos en el análisis, comprometiendo la validez de los resultados. Por esta razón, se decide excluir esta variable del análisis.

En el caso de las variables medical_specialty y payer_code, los porcentajes de valores faltantes son de 49.08% y 39.55%, respectivamente. Estos porcentajes no son lo suficientemente bajos como para aplicar técnicas de imputación sin riesgo de introducir sesgos, pero tampoco tan altos como para justificar directamente su eliminación del análisis. Por tanto, recurriremos a agrupar estos NaN es una nueva categoria llamada “Unknown”.

Las variables race, diag_1, diag_2 y diag_3 tienen un porcentaje de NaN del 2.23%, 1.29%, 0.35% y 0.02 respectivamente. Al ser porcentajes pequeñoS recurriremos a hacer imputación por la moda para los tres casos.

5.1.1. Tratamiento de valores faltantes:

# Eliminar la columna 'weight'
df <- df %>% select(-weight)

# Reemplazar NA por 'Unknown' para variables con alto % de faltantes
df <- df %>%
  mutate(
    medical_specialty = ifelse(is.na(medical_specialty), "Unknown", medical_specialty),
    payer_code = ifelse(is.na(payer_code), "Unknown", payer_code)
  )

# Imputación por la moda para ciertas variables
var_imputar <- c("race", "diag_1", "diag_2", "diag_3")

for (name_var in var_imputar) {
  moda <- df %>%
    filter(!is.na(.data[[name_var]])) %>%
    count(.data[[name_var]]) %>%
    arrange(desc(n)) %>%
    slice(1) %>%
    pull(.data[[name_var]])
  
  df[[name_var]][is.na(df[[name_var]])] <- moda
}

head(df)
##   encounter_id patient_nbr            race gender     age admission_type_id
## 1      2278392     8222157       Caucasian Female  [0-10)                 6
## 2       149190    55629189       Caucasian Female [10-20)                 1
## 3        64410    86047875 AfricanAmerican Female [20-30)                 1
## 4       500364    82442376       Caucasian   Male [30-40)                 1
## 5        16680    42519267       Caucasian   Male [40-50)                 1
## 6        35754    82637451       Caucasian   Male [50-60)                 2
##   discharge_disposition_id admission_source_id time_in_hospital payer_code
## 1                       25                   1                1    Unknown
## 2                        1                   7                3    Unknown
## 3                        1                   7                2    Unknown
## 4                        1                   7                2    Unknown
## 5                        1                   7                1    Unknown
## 6                        1                   2                3    Unknown
##          medical_specialty num_lab_procedures num_procedures num_medications
## 1 Pediatrics-Endocrinology                 41              0               1
## 2                  Unknown                 59              0              18
## 3                  Unknown                 11              5              13
## 4                  Unknown                 44              1              16
## 5                  Unknown                 51              0               8
## 6                  Unknown                 31              6              16
##   number_outpatient number_emergency number_inpatient
## 1                 0                0                0
## 2                 0                0                0
## 3                 2                0                1
## 4                 0                0                0
## 5                 0                0                0
## 6                 0                0                0
##                                   diag_1       diag_2
## 1                               Diabetes Circulatorio
## 2 Endocrino y metabolismo (sin diabetes)     Diabetes
## 3                   Embarazo y puerperio     Diabetes
## 4             Infecciosas y parasitarias     Diabetes
## 5                             Neoplasmas   Neoplasmas
## 6                           Circulatorio Circulatorio
##                                   diag_3 number_diagnoses max_glu_serum
## 1                           Circulatorio                1          None
## 2 Endocrino y metabolismo (sin diabetes)                9          None
## 3                        Causas externas                6          None
## 4                           Circulatorio                7          None
## 5                               Diabetes                5          None
## 6                               Diabetes                9          None
##   A1Cresult metformin repaglinide nateglinide chlorpropamide glimepiride
## 1      None        No          No          No             No          No
## 2      None        No          No          No             No          No
## 3      None        No          No          No             No          No
## 4      None        No          No          No             No          No
## 5      None        No          No          No             No          No
## 6      None        No          No          No             No          No
##   acetohexamide glipizide glyburide tolbutamide pioglitazone rosiglitazone
## 1            No        No        No          No           No            No
## 2            No        No        No          No           No            No
## 3            No    Steady        No          No           No            No
## 4            No        No        No          No           No            No
## 5            No    Steady        No          No           No            No
## 6            No        No        No          No           No            No
##   acarbose miglitol troglitazone tolazamide examide citoglipton insulin
## 1       No       No           No         No      No          No      No
## 2       No       No           No         No      No          No      Up
## 3       No       No           No         No      No          No      No
## 4       No       No           No         No      No          No      Up
## 5       No       No           No         No      No          No  Steady
## 6       No       No           No         No      No          No  Steady
##   glyburide.metformin glipizide.metformin glimepiride.pioglitazone
## 1                  No                  No                       No
## 2                  No                  No                       No
## 3                  No                  No                       No
## 4                  No                  No                       No
## 5                  No                  No                       No
## 6                  No                  No                       No
##   metformin.rosiglitazone metformin.pioglitazone change diabetesMed readmitted
## 1                      No                     No     No          No         NO
## 2                      No                     No     Ch         Yes        >30
## 3                      No                     No     No         Yes         NO
## 4                      No                     No     Ch         Yes         NO
## 5                      No                     No     Ch         Yes         NO
## 6                      No                     No     No         Yes        >30

5.2 Codificar Variables Categoricas:

En este dataset nos encontramos con una gran proporción de variables categóricas, las cuales debemos codificar para que puedan ser utilizadas en análisis posteriores.

# Seleccionar columnas categóricas
cat_cols <- names(df)[sapply(df, is.character) | sapply(df, is.factor)]

# Lista para guardar los mapeos
mapeos <- list()

# Codificar y guardar mapeo
for (col in cat_cols) {
  factor_col <- as.factor(df[[col]])
  niveles <- levels(factor_col)
  
  # Guardar mapeo
  mapeos[[col]] <- data.frame(
    Categoria = niveles,
    Codigo = seq_along(niveles) - 1
  )
  
  # Reemplazar en el DataFrame
  df[[col]] <- as.numeric(factor_col) - 1
}

# Mostrar mapeos
for (col in names(mapeos)) {
  cat("Columna:", col, "\n")
  print(mapeos[[col]])
  cat("\n")
}
## Columna: race 
##         Categoria Codigo
## 1 AfricanAmerican      0
## 2           Asian      1
## 3       Caucasian      2
## 4        Hispanic      3
## 5           Other      4
## 
## Columna: gender 
##         Categoria Codigo
## 1          Female      0
## 2            Male      1
## 3 Unknown/Invalid      2
## 
## Columna: age 
##    Categoria Codigo
## 1     [0-10)      0
## 2    [10-20)      1
## 3    [20-30)      2
## 4    [30-40)      3
## 5    [40-50)      4
## 6    [50-60)      5
## 7    [60-70)      6
## 8    [70-80)      7
## 9    [80-90)      8
## 10  [90-100)      9
## 
## Columna: payer_code 
##    Categoria Codigo
## 1         BC      0
## 2         CH      1
## 3         CM      2
## 4         CP      3
## 5         DM      4
## 6         FR      5
## 7         HM      6
## 8         MC      7
## 9         MD      8
## 10        MP      9
## 11        OG     10
## 12        OT     11
## 13        PO     12
## 14        SI     13
## 15        SP     14
## 16        UN     15
## 17   Unknown     16
## 18        WC     17
## 
## Columna: medical_specialty 
##                               Categoria Codigo
## 1                  AllergyandImmunology      0
## 2                        Anesthesiology      1
## 3              Anesthesiology-Pediatric      2
## 4                            Cardiology      3
## 5                  Cardiology-Pediatric      4
## 6                               DCPTEAM      5
## 7                             Dentistry      6
## 8                           Dermatology      7
## 9                      Emergency/Trauma      8
## 10                        Endocrinology      9
## 11             Endocrinology-Metabolism     10
## 12               Family/GeneralPractice     11
## 13                     Gastroenterology     12
## 14                           Gynecology     13
## 15                           Hematology     14
## 16                  Hematology/Oncology     15
## 17                          Hospitalist     16
## 18                   InfectiousDiseases     17
## 19                     InternalMedicine     18
## 20                           Nephrology     19
## 21                            Neurology     20
## 22                      Neurophysiology     21
## 23 Obsterics&Gynecology-GynecologicOnco     22
## 24                           Obstetrics     23
## 25              ObstetricsandGynecology     24
## 26                             Oncology     25
## 27                        Ophthalmology     26
## 28                          Orthopedics     27
## 29           Orthopedics-Reconstructive     28
## 30                            Osteopath     29
## 31                       Otolaryngology     30
## 32                     OutreachServices     31
## 33                            Pathology     32
## 34                           Pediatrics     33
## 35      Pediatrics-AllergyandImmunology     34
## 36              Pediatrics-CriticalCare     35
## 37         Pediatrics-EmergencyMedicine     36
## 38             Pediatrics-Endocrinology     37
## 39       Pediatrics-Hematology-Oncology     38
## 40        Pediatrics-InfectiousDiseases     39
## 41                 Pediatrics-Neurology     40
## 42               Pediatrics-Pulmonology     41
## 43                         Perinatology     42
## 44    PhysicalMedicineandRehabilitation     43
## 45                    PhysicianNotFound     44
## 46                             Podiatry     45
## 47                           Proctology     46
## 48                           Psychiatry     47
## 49                 Psychiatry-Addictive     48
## 50          Psychiatry-Child/Adolescent     49
## 51                           Psychology     50
## 52                          Pulmonology     51
## 53                          Radiologist     52
## 54                            Radiology     53
## 55                             Resident     54
## 56                         Rheumatology     55
## 57                               Speech     56
## 58                       SportsMedicine     57
## 59                              Surgeon     58
## 60               Surgery-Cardiovascular     59
## 61      Surgery-Cardiovascular/Thoracic     60
## 62                 Surgery-Colon&Rectal     61
## 63                      Surgery-General     62
## 64                Surgery-Maxillofacial     63
## 65                        Surgery-Neuro     64
## 66                    Surgery-Pediatric     65
## 67                      Surgery-Plastic     66
## 68     Surgery-PlasticwithinHeadandNeck     67
## 69                     Surgery-Thoracic     68
## 70                     Surgery-Vascular     69
## 71                    SurgicalSpecialty     70
## 72                              Unknown     71
## 73                              Urology     72
## 
## Columna: diag_1 
##                                 Categoria Codigo
## 1                    Anomalías congénitas      0
## 2                         Causas externas      1
## 3                            Circulatorio      2
## 4                                Diabetes      3
## 5                               Digestivo      4
## 6                    Embarazo y puerperio      5
## 7  Endocrino y metabolismo (sin diabetes)      6
## 8                          Genitourinario      7
## 9                                  Herida      8
## 10             Infecciosas y parasitarias      9
## 11                     Musculoesquelético     10
## 12                             Neoplasmas     11
## 13                Órganos de los sentidos     12
## 14                                   Otro     13
## 15               Piel y tejido subcutáneo     14
## 16                           Respiratorio     15
## 17       Sangre y órganos hematopoyéticos     16
## 18                 Síntomas mal definidos     17
## 19                       Sistema nervioso     18
## 20                    Trastornos mentales     19
## 
## Columna: diag_2 
##                                 Categoria Codigo
## 1                    Anomalías congénitas      0
## 2                         Causas externas      1
## 3                            Circulatorio      2
## 4                                Diabetes      3
## 5                               Digestivo      4
## 6                    Embarazo y puerperio      5
## 7  Endocrino y metabolismo (sin diabetes)      6
## 8                          Genitourinario      7
## 9                                  Herida      8
## 10             Infecciosas y parasitarias      9
## 11                     Musculoesquelético     10
## 12                             Neoplasmas     11
## 13                Órganos de los sentidos     12
## 14                                   Otro     13
## 15               Piel y tejido subcutáneo     14
## 16                           Respiratorio     15
## 17       Sangre y órganos hematopoyéticos     16
## 18                 Síntomas mal definidos     17
## 19                       Sistema nervioso     18
## 20                    Trastornos mentales     19
## 
## Columna: diag_3 
##                                 Categoria Codigo
## 1                    Anomalías congénitas      0
## 2                         Causas externas      1
## 3                            Circulatorio      2
## 4                                Diabetes      3
## 5                               Digestivo      4
## 6                    Embarazo y puerperio      5
## 7  Endocrino y metabolismo (sin diabetes)      6
## 8                          Genitourinario      7
## 9                                  Herida      8
## 10             Infecciosas y parasitarias      9
## 11                     Musculoesquelético     10
## 12                             Neoplasmas     11
## 13                Órganos de los sentidos     12
## 14                                   Otro     13
## 15               Piel y tejido subcutáneo     14
## 16                           Respiratorio     15
## 17       Sangre y órganos hematopoyéticos     16
## 18                 Síntomas mal definidos     17
## 19                       Sistema nervioso     18
## 20                    Trastornos mentales     19
## 
## Columna: max_glu_serum 
##   Categoria Codigo
## 1      >200      0
## 2      >300      1
## 3      None      2
## 4      Norm      3
## 
## Columna: A1Cresult 
##   Categoria Codigo
## 1        >7      0
## 2        >8      1
## 3      None      2
## 4      Norm      3
## 
## Columna: metformin 
##   Categoria Codigo
## 1      Down      0
## 2        No      1
## 3    Steady      2
## 4        Up      3
## 
## Columna: repaglinide 
##   Categoria Codigo
## 1      Down      0
## 2        No      1
## 3    Steady      2
## 4        Up      3
## 
## Columna: nateglinide 
##   Categoria Codigo
## 1      Down      0
## 2        No      1
## 3    Steady      2
## 4        Up      3
## 
## Columna: chlorpropamide 
##   Categoria Codigo
## 1      Down      0
## 2        No      1
## 3    Steady      2
## 4        Up      3
## 
## Columna: glimepiride 
##   Categoria Codigo
## 1      Down      0
## 2        No      1
## 3    Steady      2
## 4        Up      3
## 
## Columna: acetohexamide 
##   Categoria Codigo
## 1        No      0
## 2    Steady      1
## 
## Columna: glipizide 
##   Categoria Codigo
## 1      Down      0
## 2        No      1
## 3    Steady      2
## 4        Up      3
## 
## Columna: glyburide 
##   Categoria Codigo
## 1      Down      0
## 2        No      1
## 3    Steady      2
## 4        Up      3
## 
## Columna: tolbutamide 
##   Categoria Codigo
## 1        No      0
## 2    Steady      1
## 
## Columna: pioglitazone 
##   Categoria Codigo
## 1      Down      0
## 2        No      1
## 3    Steady      2
## 4        Up      3
## 
## Columna: rosiglitazone 
##   Categoria Codigo
## 1      Down      0
## 2        No      1
## 3    Steady      2
## 4        Up      3
## 
## Columna: acarbose 
##   Categoria Codigo
## 1      Down      0
## 2        No      1
## 3    Steady      2
## 4        Up      3
## 
## Columna: miglitol 
##   Categoria Codigo
## 1      Down      0
## 2        No      1
## 3    Steady      2
## 4        Up      3
## 
## Columna: troglitazone 
##   Categoria Codigo
## 1        No      0
## 2    Steady      1
## 
## Columna: tolazamide 
##   Categoria Codigo
## 1        No      0
## 2    Steady      1
## 3        Up      2
## 
## Columna: examide 
##   Categoria Codigo
## 1        No      0
## 
## Columna: citoglipton 
##   Categoria Codigo
## 1        No      0
## 
## Columna: insulin 
##   Categoria Codigo
## 1      Down      0
## 2        No      1
## 3    Steady      2
## 4        Up      3
## 
## Columna: glyburide.metformin 
##   Categoria Codigo
## 1      Down      0
## 2        No      1
## 3    Steady      2
## 4        Up      3
## 
## Columna: glipizide.metformin 
##   Categoria Codigo
## 1        No      0
## 2    Steady      1
## 
## Columna: glimepiride.pioglitazone 
##   Categoria Codigo
## 1        No      0
## 2    Steady      1
## 
## Columna: metformin.rosiglitazone 
##   Categoria Codigo
## 1        No      0
## 2    Steady      1
## 
## Columna: metformin.pioglitazone 
##   Categoria Codigo
## 1        No      0
## 2    Steady      1
## 
## Columna: change 
##   Categoria Codigo
## 1        Ch      0
## 2        No      1
## 
## Columna: diabetesMed 
##   Categoria Codigo
## 1        No      0
## 2       Yes      1
## 
## Columna: readmitted 
##   Categoria Codigo
## 1       <30      0
## 2       >30      1
## 3        NO      2

La codificación se completó correctamente, y podemos asi mismo que numero fue asignado a cada etiqueta.

6. Análisis Descriptivo:

6.1 Variables Numéricas:

6.1.1 Resumen Estadístico:

# Definir las columnas numéricas
columnas_numericas <- c(
  "time_in_hospital", "num_lab_procedures", "num_procedures", "num_medications",
  "number_outpatient", "number_emergency", "number_inpatient", "number_diagnoses"
)

# Filtrar solo esas columnas
numericas <- df[, columnas_numericas]

# Mostrar resumen estadístico y transponerlo
resumen <- summary(numericas)
t(resumen)
##                                                                         
## time_in_hospital   Min.   : 1.000    1st Qu.: 2.000    Median : 4.000   
## num_lab_procedures Min.   :  1.0     1st Qu.: 31.0     Median : 44.0    
## num_procedures     Min.   :0.00      1st Qu.:0.00      Median :1.00     
## num_medications    Min.   : 1.00     1st Qu.:10.00     Median :15.00    
## number_outpatient  Min.   : 0.0000   1st Qu.: 0.0000   Median : 0.0000  
## number_emergency   Min.   : 0.0000   1st Qu.: 0.0000   Median : 0.0000  
## number_inpatient   Min.   : 0.0000   1st Qu.: 0.0000   Median : 0.0000  
## number_diagnoses   Min.   : 1.000    1st Qu.: 6.000    Median : 8.000   
##                                                                         
## time_in_hospital   Mean   : 4.396    3rd Qu.: 6.000    Max.   :14.000   
## num_lab_procedures Mean   : 43.1     3rd Qu.: 57.0     Max.   :132.0    
## num_procedures     Mean   :1.34      3rd Qu.:2.00      Max.   :6.00     
## num_medications    Mean   :16.02     3rd Qu.:20.00     Max.   :81.00    
## number_outpatient  Mean   : 0.3694   3rd Qu.: 0.0000   Max.   :42.0000  
## number_emergency   Mean   : 0.1978   3rd Qu.: 0.0000   Max.   :76.0000  
## number_inpatient   Mean   : 0.6356   3rd Qu.: 1.0000   Max.   :21.0000  
## number_diagnoses   Mean   : 7.423    3rd Qu.: 9.000    Max.   :16.000

6.1.2 Graficos:

# 1. Histograma: tiempo en hospital
p1 <- ggplot(df, aes(x = time_in_hospital)) +
  geom_histogram(binwidth = 1, fill = "red", color = "black") +
  ggtitle("Distribución de tiempo en hospital")

# 2. Histograma: procedimientos de laboratorio
p2 <- ggplot(df, aes(x = num_lab_procedures)) +
  geom_histogram(bins = 30, fill = "red", color = "black") +
  ggtitle("Distribución # procedimientos de lab")

# 3. Histograma: # procedimientos
p3 <- ggplot(df, aes(x = num_procedures)) +
  geom_histogram(binwidth = 1, fill = "red", color = "black") +
  ggtitle("Distribución de # procedimientos")

# 4. Histograma: # medicamentos
p4 <- ggplot(df, aes(x = num_medications)) +
  geom_histogram(bins = 30, fill = "red", color = "black") +
  ggtitle("Distribución de # medicamentos administrados")

# 5. Conteo: visitas ambulatorias
p5 <- ggplot(df, aes(x = factor(number_outpatient))) +
  geom_bar(fill = "tomato", color = "black") +
  ggtitle("Distribución de # visitas ambulatorias") +
  theme(axis.text.x = element_text(angle = 90, hjust = 1))

# 6. Conteo: visitas urgencias
p6 <- ggplot(df, aes(x = factor(number_emergency))) +
  geom_bar(fill = "tomato", color = "black") +
  ggtitle("Distribución de # visitas urgencias") +
  theme(axis.text.x = element_text(angle = 90, hjust = 1))

# 7. Histograma: ingresos hospitalarios
p7 <- ggplot(df, aes(x = number_inpatient)) +
  geom_histogram(bins = 30, fill = "red", color = "black") +
  ggtitle("Distribución de # Ingresos Hospitalarios")

# 8. Histograma: diagnósticos
p8 <- ggplot(df, aes(x = number_diagnoses)) +
  geom_histogram(binwidth = 1, fill = "red", color = "black") +
  ggtitle("Distribución de # Diagnósticos Registrados")

# Organizar en grilla (4 filas, 2 columnas)
grid.arrange(p1, p2, p3, p4, p5, p6, p7, p8, ncol = 2)

  • Tiempo en el Hospital (time_in_hospital): La gráfica muestra una distribución claramente sesgada a la derecha. La mayoría de los pacientes permanecen en el hospital entre 2 y 5 días, siendo 4 días la duración más frecuente. A medida que aumenta el número de días, la frecuencia disminuye significativamente, lo que indica que solo una pequeña proporción de pacientes permanece más de 10 días hospitalizado.
  • Numero de Procedimientos de Laboratorio (num_lab_procedures): La distribución es ligeramente simétrica, con una concentración de valores entre 40 y 60 procedimientos, siendo alrededor de 50 la cantidad más frecuente. Aunque hay presencia de valores cercanos a cero, su frecuencia es considerablemente menor. Esta variable refleja una variabilidad moderada y una tendencia central bien definida.
  • Número de Procedimientos Distintos(num_procedures): Se observa una distribución marcadamente sesgada a la derecha, ya que la mayor parte de los pacientes recibió solo un procedimiento. La frecuencia disminuye conforme aumenta el número de procedimientos, lo que indica que pocos pacientes son sometidos a más de 3 o 4 procedimientos.
  • Número de medicamentos (num_medications): La gráfica indica que la mayoría de los pacientes recibió entre 10 y 20 medicamentos, siendo esta la moda. La distribución está ligeramente sesgada a la derecha, ya que existe un número reducido de pacientes a quienes se les administraron más de 40 medicamentos, aunque en menor proporción.
  • Número de visitas ambulatorias (number_outpatient): Esta variable muestra una distribución altamente sesgada a la derecha, con una fuerte concentración de pacientes que no registraron visitas ambulatorias (valor 0). Existen algunos valores atípicos con más de 20 visitas, pero representan una fracción muy pequeña de los casos.
  • Número de visitas a urgencias (number_emergency): Esta variable presenta una distribución fuertemente sesgada a la derecha, donde la gran mayoría de los pacientes no tuvo ninguna visita a urgencias. Las frecuencias caen drásticamente con el aumento en el número de visitas.
  • Número de ingresos hospitalarios (number_inpatient): Se evidencia también un sesgo a la derecha, ya que la mayoría de los pacientes no reportaron ingresos hospitalarios recientes. Solo una pequeña parte de la población muestra múltiples ingresos, y estos casos son poco frecuentes.
  • Número de diagnósticos registrados (number_diagnoses ): Esta muestra una distribución sesgada a la izquierda, con una clara concentración de pacientes que tienen 10 diagnósticos registrados, lo que representa el valor más frecuente. Los valores más bajos son menos comunes, lo que indica que la mayoría de los pacientes presenta un número alto de diagnósticos documentados.

6.1.3 Outliers:

# Crear lista de gráficos
plots <- lapply(columnas_numericas, function(col) {
  ggplot(df, aes_string(x = col)) +
    geom_boxplot(fill = "green", color = "black") +
    coord_flip() +  # Para que sean horizontales
    ggtitle(paste("Diagrama:", col)) +
    xlab(col) +
    theme_minimal()
})
## Warning: `aes_string()` was deprecated in ggplot2 3.0.0.
## ℹ Please use tidy evaluation idioms with `aes()`.
## ℹ See also `vignette("ggplot2-in-packages")` for more information.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
# Mostrar en cuadrícula 2x2
grid.arrange(grobs = plots, ncol = 3)

Comenzando desde la parte superior izquierda, se observa el diagrama de caja correspondiente a la variable Tiempo en el Hospital (time_in_hospital). Este gráfico muestra que la mayoría de los pacientes estuvo hospitalizada entre 2 y 6 días, lo que indica una concentración de valores en ese rango. La mediana se sitúa aproximadamente en 4 días. Se aprecia una distribución ligeramente sesgada a la derecha, ya que la mayor parte de los datos se encuentra en los valores más bajos. Además, se identifican dos valores atípicos en 13 y 14 días, lo que sugiere que unos pocos pacientes tuvieron estancias hospitalarias significativamente más prolongadas que el promedio.

A su derecha, el diagrama de caja correspondiente a la variable Número de Procedimientos de Laboratorio (num_lab_procedures) muestra que la mayoría de los pacientes se sometió a entre 30 y 58 procedimientos de laboratorio, con una mediana cercana a los 45. Además, se observan múltiples valores atípicos por encima de los 97 procedimientos aproximadamente, lo que indica que algunos pacientes fueron sometidos a una cantidad inusualmente alta de exámenes.

En la parte superior derecha se encuentra el diagrama de caja correspondiente a la variable Número de Procedimientos (num_procedures). En este gráfico se observa que la mayoría de los pacientes se sometió entre 0 y 3 procedimientos, con una mediana situada en 1. La distribución presenta un sesgo hacia la derecha, ya que la concentración de datos se encuentra en los valores más bajos. Se identifican algunos valores atípicos que superan los 5 procedimientos, lo cual sugiere que ciertos pacientes requirieron intervenciones médicas significativamente más numerosas que el promedio.

Continuando en la parte central izquierda, se encuentra la gráfica de la variable Número de Medicamentos (num_medications). Esta indica que a la mayoría de los pacientes se les receta entre 10 y 20 medicamentos. La mediana se sitúa aproximadamente en 14 medicamentos. La distribución presenta un claro sesgo a la derecha, evidenciado por una gran cantidad de valores atípicos que superan los 35 medicamentos, alcanzando incluso cifras cercanas a 85. Esto sugiere que, aunque la mayoría de los pacientes recibió una cantidad moderada de medicamentos, existe un subconjunto que requirió tratamientos mucho más complejos, posiblemente debido a la presencia de múltiples complicaciones clínicas.

En el centro de la imagen, la variable Número de Consultas Ambulatorias Previas (number_outpatient) presenta una distribución en la que la mayoría de los valores se ubica en 0, indicando que la mayoría de los pacientes no tuvo consultas ambulatorias previas al ingreso hospitalario. Sin embargo, se observan algunos valores atípicos que superan las 10 consultas, alcanzando cifras cercanas a 40, lo que refleja casos excepcionales con un seguimiento ambulatorio muy frecuente antes de la hospitalización.

A su derecha, el diagrama de caja de la variable Número de Visitas a Urgencias (number_emergency) muestra una alta concentración de valores en 0, indicando que la mayoría de los pacientes no acudió a urgencias en el periodo previo al ingreso. No obstante, existen múltiples valores atípicos, algunos de ellos muy elevados, que superan las 60 visitas, lo que apunta a pacientes con necesidades de atención urgente recurrente, posiblemente debido a enfermedades crónicas descompensadas o problemas de salud agudos repetitivos.

En la parte inferior izquierda se encuentra el diagrama de caja de la variable Número de Hospitalizaciones Previas (number_inpatient). La distribución muestra que la gran mayoría de los pacientes no había tenido hospitalizaciones previas recientes, lo que se refleja en la concentración de valores en 0. Aun así, se observan valores atípicos que superan las 15 hospitalizaciones, llegando a un máximo cercano a 21, lo cual indica casos de pacientes con historial clínico complejo y frecuentes ingresos.

Por último, en la parte inferior derecha, el diagrama de caja correspondiente a la variable Número de Diagnósticos Registrados (number_diagnoses) evidencia una distribución relativamente simétrica, ya que la mediana se encuentra en una posición central, alrededor de los 8 diagnósticos por paciente. La mayoría de los datos se concentra entre aproximadamente 6 y 9 diagnósticos, lo que indica una baja dispersión en la parte central de la distribución. Se identifican cuatro valores atípicos: uno inferior cercano a 1 diagnóstico, y tres superiores, a partir de los 14 diagnósticos por paciente. Estos casos extremos indican que, aunque la mayoría de los pacientes recibe un número moderado de diagnósticos, existen situaciones excepcionales con cargas diagnósticas significativamente mayores o menores. En conjunto, este gráfico sugiere que la práctica médica tiende a generar entre 6 y 9 diagnósticos por paciente, aunque en ciertos casos particulares se observan registros considerablemente más extremos.

Filtro de Hampel + Capping: Procedemos a utilizar el filtro de Hampel para identificar los outliers, combinandolo con Capping para tartarlos

hampel_capping <- function(x, k = 7, t0 = 3, lower_pct = 0.05, upper_pct = 0.95) {
  
  # Detectar outliers con Hampel
  hamp <- hampel(x, k = k, t0 = t0)
  outliers_idx <- hamp$ind
  
  if (length(outliers_idx) > 0) {
    # Calcular límites por percentiles
    lower_cap <- quantile(x, lower_pct, na.rm = TRUE)
    upper_cap <- quantile(x, upper_pct, na.rm = TRUE)
    
    # Sustituir valores fuera de rango por los percentiles
    x[outliers_idx][x[outliers_idx] < lower_cap] <- lower_cap
    x[outliers_idx][x[outliers_idx] > upper_cap] <- upper_cap
  }
  
  return(x)
}

for (col in columnas_numericas) {
  df[[col]] <- hampel_capping(df[[col]], k = 7, t0 = 3)
}
# Crear lista de gráficos
plots <- lapply(columnas_numericas, function(col) {
  ggplot(df, aes_string(x = col)) +
    geom_boxplot(fill = "blue", color = "black") +
    coord_flip() +  # Para que sean horizontales
    ggtitle(paste("Diagrama", col)) +
    xlab(col) +
    theme_minimal()
})

# Mostrar en cuadrícula 2x2
grid.arrange(grobs = plots, ncol = 3)

6.1.3.1 Evaluación del tratamiento de outliers:

Al comparar los diagramas de caja antes y después del tratamiento de outliers, se observa que el procedimiento redujo significativamente la presencia de valores extremos:

  • Antes del tratamiento:
    • Variables como num_medications, num_lab_procedures, number_emergency, number_inpatient y number_outpatient presentaban numerosos outliers alejados del resto de los datos.
    • La dispersión era considerablemente mayor, evidenciando alta variabilidad y la presencia de datos extremos que podían distorsionar el análisis estadístico.
  • Después del tratamiento:
    • La mayoría de los valores extremos desaparecieron o se redujeron notablemente.
    • El rango intercuartílico se mantiene, pero los bigotes del boxplot son más cortos y cercanos al cuerpo de los datos. Esto sugiere que la imputación ajustó los valores atípicos al rango esperado, estabilizando la distribución de las variables.

6.1.4 Correlación:

# Si no tienes instalados los paquetes necesarios
# install.packages(c("ggplot2", "corrplot"))

library(corrplot)
## corrplot 0.95 loaded
# Calcular la matriz de correlaciones
cor_matrix <- cor(df[, columnas_numericas], use = "complete.obs")

# Graficar la matriz de correlaciones
corrplot(cor_matrix,
         method = "color",      # Colores en lugar de círculos
         type = "upper",        # Solo la parte superior
         tl.col = "black",      # Color de las etiquetas
         tl.srt = 45,           # Rotación de las etiquetas
         addCoef.col = "black", # Mostrar los valores numéricos
         col = colorRampPalette(c("blue", "white", "red"))(200),
         title = "Matriz de correlación entre variables numéricas",
         mar = c(0, 0, 2, 0))   # Márgenes para el título

Interpretación de la matriz de correlación

La matriz de correlación muestra las relaciones lineales entre las variables numéricas del conjunto de datos:

  • Correlaciones moderadas
    • time_in_hospital presenta correlación positiva moderada con num_medications (0.47) y con num_lab_procedures (0.32), lo que sugiere que a mayor tiempo de hospitalización suele aumentar el número de medicamentos administrados y de procedimientos de laboratorio realizados.
    • num_procedures y num_medications tienen correlación moderada (0.36), indicando que más procedimientos pueden estar asociados con más medicamentos.
  • Correlaciones bajas o débiles
    • La mayoría de las demás correlaciones son cercanas a 0, lo que indica relaciones muy débiles o inexistentes entre dichas variables.
    • Ejemplo: number_outpatient con time_in_hospital (0.00) o num_lab_procedures (-0.03) muestran prácticamente nula relación.
  • Correlaciones negativas
    • Existen algunas relaciones negativas muy débiles, como num_medications con time_in_hospital (-0.02) o num_procedures con number_inpatient (-0.07), lo que implica ausencia de relación lineal relevante.

No se observan correlaciones muy fuertes (≥ 0.8) que indiquen problemas de multicolinealidad grave. Sin embargo, las correlaciones moderadas encontradas, especialmente entre el tiempo de hospitalización, medicamentos y procedimientos, pueden ser relevantes para análisis posteriores.

6.2 Variables Categoricas:

6.2.1 Resumen

# Crear lista con el resumen de variables categóricas
summary_list <- lapply(cat_cols, function(col) {
  total <- nrow(df)
  n_missing <- sum(is.na(df[[col]]))
  n_unique <- length(unique(na.omit(df[[col]])))
  freq_table <- table(df[[col]], useNA = "no") %>% sort(decreasing = TRUE)
  top <- names(freq_table)[1]
  freq <- as.numeric(freq_table[1])
  top_pct <- (freq / total) * 100
  
  data.frame(
    Variable = col,
    Categorías_únicas = n_unique,
    Valor_más_frecuente = top,
    Frecuencia = freq,
    Porcentaje_del_más_frecuente = round(top_pct, 2),
    Nulos = n_missing
  )
})

# Convertir a DataFrame y ordenar
summary_df <- bind_rows(summary_list) %>%
  arrange(desc(Categorías_únicas))

# Mostrar como tabla (mejorado con knitr o DT si es interactivo)
print(summary_df)
##                    Variable Categorías_únicas Valor_más_frecuente Frecuencia
## 1         medical_specialty                73                  71      49949
## 2                    diag_1                20                   2      30458
## 3                    diag_2                20                   2      32239
## 4                    diag_3                20                   2      31729
## 5                payer_code                18                  16      40256
## 6                       age                10                   7      26068
## 7                      race                 5                   2      78372
## 8             max_glu_serum                 4                   2      96420
## 9                 A1Cresult                 4                   2      84748
## 10                metformin                 4                   1      81778
## 11              repaglinide                 4                   1     100227
## 12              nateglinide                 4                   1     101063
## 13           chlorpropamide                 4                   1     101680
## 14              glimepiride                 4                   1      96575
## 15                glipizide                 4                   1      89080
## 16                glyburide                 4                   1      91116
## 17             pioglitazone                 4                   1      94438
## 18            rosiglitazone                 4                   1      95401
## 19                 acarbose                 4                   1     101458
## 20                 miglitol                 4                   1     101728
## 21                  insulin                 4                   1      47383
## 22      glyburide.metformin                 4                   1     101060
## 23                   gender                 3                   0      54708
## 24               tolazamide                 3                   0     101727
## 25               readmitted                 3                   2      54864
## 26            acetohexamide                 2                   0     101765
## 27              tolbutamide                 2                   0     101743
## 28             troglitazone                 2                   0     101763
## 29      glipizide.metformin                 2                   0     101753
## 30 glimepiride.pioglitazone                 2                   0     101765
## 31  metformin.rosiglitazone                 2                   0     101764
## 32   metformin.pioglitazone                 2                   0     101765
## 33                   change                 2                   1      54755
## 34              diabetesMed                 2                   1      78363
## 35                  examide                 1                   0     101766
## 36              citoglipton                 1                   0     101766
##    Porcentaje_del_más_frecuente Nulos
## 1                         49.08     0
## 2                         29.93     0
## 3                         31.68     0
## 4                         31.18     0
## 5                         39.56     0
## 6                         25.62     0
## 7                         77.01     0
## 8                         94.75     0
## 9                         83.28     0
## 10                        80.36     0
## 11                        98.49     0
## 12                        99.31     0
## 13                        99.92     0
## 14                        94.90     0
## 15                        87.53     0
## 16                        89.53     0
## 17                        92.80     0
## 18                        93.75     0
## 19                        99.70     0
## 20                        99.96     0
## 21                        46.56     0
## 22                        99.31     0
## 23                        53.76     0
## 24                        99.96     0
## 25                        53.91     0
## 26                       100.00     0
## 27                        99.98     0
## 28                       100.00     0
## 29                        99.99     0
## 30                       100.00     0
## 31                       100.00     0
## 32                       100.00     0
## 33                        53.80     0
## 34                        77.00     0
## 35                       100.00     0
## 36                       100.00     0

El resumen de las variables categóricas revela una alta proporción de valores dominantes en la mayoría de las variables. Por ejemplo, variables como glyburide-metformin, metformin-pioglitazone, glipizide-metformin, troglitazone, entre otras, presentan una distribución extremadamente desbalanceada, con un único valor que representa el 100% o casi el 100% de los casos, lo cual indica una falta de variabilidad y sugiere que podrían no aportar información útil al modelo o análisis. En contraste, variables como race, gender y readmitted muestran distribuciones más heterogéneas, con porcentajes más bajos del valor más frecuente, lo que las convierte en candidatas más informativas. Asimismo, algunas variables como medical_specialty y payer_code presentan una alta cantidad de categorías (73 y 18 respectivamente), lo cual podría introducir complejidad en el análisis y requerir estrategias como agrupación o codificación especial. Finalmente, ninguna de las variables categóricas contiene valores nulos, lo cual facilita su procesamiento posterior.

Gráficos

En primer lugar, se separan las variables por categoría, es ecir, variables demográficas, de identificación y demás.

# Definición de grupos de variables categóricas
cat_ident <- c(
    'encounter_id', 'patient_nbr'
)
n_cols_ident <- length(cat_ident)

cat_dem_ing <- c(
    'race', 'gender', 'age', 'admission_type_id',
    'discharge_disposition_id', 'admission_source_id',
    'time_in_hospital'
)
n_cols_dem_ing <- length(cat_dem_ing)

cat_prue_proced <- c(
    'num_lab_procedures', 'num_procedures', 'num_medications',
    'number_outpatient', 'number_emergency', 'number_inpatient',
    'number_diagnoses'
)
n_cols_prue_proced <- length(cat_prue_proced)

cat_diag_princ <- c(
    'diag_1', 'diag_2', 'diag_3' 
)
n_cols_diag_princ <- length(cat_diag_princ)

cat_resultados_lab <- c(
    'max_glu_serum', 'A1Cresult'
)
n_cols_resultados_lab <- length(cat_resultados_lab)

cat_meds <- c(
    'metformin', 'repaglinide', 'nateglinide', 'chlorpropamide',
    'glimepiride', 'acetohexamide', 'glipizide', 'glyburide',
    'tolbutamide', 'pioglitazone', 'rosiglitazone', 'acarbose',
    'miglitol', 'troglitazone', 'tolazamide', 'examide',
    'citoglipton', 'insulin', 'glyburide-metformin',
    'glipizide-metformin', 'glimepiride-pioglitazone',
    'metformin-rosiglitazone', 'metformin-pioglitazone'
)
n_cols_meds <- length(cat_meds)

cat_control_tratamiento <- c(
    'change', 'diabetesMed'
)
n_cols_control_tratamiento <- length(cat_control_tratamiento)

cat_objetivo <- c(
    'readmitted'
)
n_cols_objetivo <- length(cat_objetivo)

# Crear un resumen de los grupos en un data.frame
grupos_categoricos <- data.frame(
  Grupo = c("Identificación", "Demográficos/Ingreso", "Pruebas/Procedimientos",
            "Diagnósticos Principales", "Resultados Laboratorio", "Medicamentos",
            "Control Tratamiento", "Objetivo"),
  Variables = c(n_cols_ident, n_cols_dem_ing, n_cols_prue_proced,
                n_cols_diag_princ, n_cols_resultados_lab, n_cols_meds,
                n_cols_control_tratamiento, n_cols_objetivo)
)

# Mostrar resumen
print(grupos_categoricos)
##                      Grupo Variables
## 1           Identificación         2
## 2     Demográficos/Ingreso         7
## 3   Pruebas/Procedimientos         7
## 4 Diagnósticos Principales         3
## 5   Resultados Laboratorio         2
## 6             Medicamentos        23
## 7      Control Tratamiento         2
## 8                 Objetivo         1

Ahora se grafican las variables por las categóricas anteriormente seleccionadas.

Distribución de variables demográficas y de ingreso

for (col in cat_dem_ing) {
  print(
    ggplot(df, aes_string(x = col, fill = col)) +
      geom_bar() +
      labs(title = paste("Distribución de  la variable ", col), x = col, y = "Frecuencia") +
      theme_minimal()
  )
}
## Warning: The following aesthetics were dropped during statistical transformation: fill.
## ℹ This can happen when ggplot fails to infer the correct grouping structure in
##   the data.
## ℹ Did you forget to specify a `group` aesthetic or to convert a numerical
##   variable into a factor?

## Warning: The following aesthetics were dropped during statistical transformation: fill.
## ℹ This can happen when ggplot fails to infer the correct grouping structure in
##   the data.
## ℹ Did you forget to specify a `group` aesthetic or to convert a numerical
##   variable into a factor?

## Warning: The following aesthetics were dropped during statistical transformation: fill.
## ℹ This can happen when ggplot fails to infer the correct grouping structure in
##   the data.
## ℹ Did you forget to specify a `group` aesthetic or to convert a numerical
##   variable into a factor?

## Warning: The following aesthetics were dropped during statistical transformation: fill.
## ℹ This can happen when ggplot fails to infer the correct grouping structure in
##   the data.
## ℹ Did you forget to specify a `group` aesthetic or to convert a numerical
##   variable into a factor?

## Warning: The following aesthetics were dropped during statistical transformation: fill.
## ℹ This can happen when ggplot fails to infer the correct grouping structure in
##   the data.
## ℹ Did you forget to specify a `group` aesthetic or to convert a numerical
##   variable into a factor?

## Warning: The following aesthetics were dropped during statistical transformation: fill.
## ℹ This can happen when ggplot fails to infer the correct grouping structure in
##   the data.
## ℹ Did you forget to specify a `group` aesthetic or to convert a numerical
##   variable into a factor?

## Warning: The following aesthetics were dropped during statistical transformation: fill.
## ℹ This can happen when ggplot fails to infer the correct grouping structure in
##   the data.
## ℹ Did you forget to specify a `group` aesthetic or to convert a numerical
##   variable into a factor?

La figura presenta la distribución de varias variables categóricas relacionadas con las características demográficas de los pacientes y su ingreso hospitalario.

  • Raza (race):
    Se observa que la mayoría de los pacientes se identifican como raza 2, lo cual, según la codificación del dataset, corresponde a pacientes caucásicos. Las otras categorías (como afroamericanos, hispanos, asiáticos y otros) tienen una representación mucho menor.

  • Género (gender):
    Hay una leve mayoría de pacientes de género 2, que corresponde a femenino, seguido por género 1, que es masculino. La categoría 0 (desconocido o inválido) es mínima.

  • Edad (age):
    La mayoría de los pacientes se encuentran entre 60 y 80 años, lo cual es coherente con el hecho de que la diabetes tipo 2 y sus complicaciones son más comunes en adultos mayores.
    Los intervalos de edad están codificados (ej. 0 = [0–10), 1 = [10–20), etc.), pero visualmente se evidencia que los valores más frecuentes son de adultos mayores.

  • Tipo de ingreso (admission_type_id):
    La categoría más frecuente es la 1, que corresponde a urgencias.
    Esto indica que la mayoría de las hospitalizaciones fueron por situaciones no planificadas.
    Otras formas de ingreso como consultas referidas o ingreso electivo son mucho menos comunes.

  • Condición de alta (discharge_disposition_id):
    Aunque esta variable tiene muchas categorías, destacan:
    la 1 (alta a casa), seguida por algunas otras como la 3 (alta a otro hospital) o la 6 (paciente fallecido).
    Esto da una idea de cómo se resolvió la hospitalización.

  • Fuente de ingreso (admission_source_id):
    Se observa un gran predominio de la categoría 7, que en este caso representa ingresos desde la sala de emergencias.
    Esto refuerza lo anterior, donde se evidenció que la mayoría de pacientes ingresan por urgencia.

  • Tiempo en el hospital (time_in_hospital):
    Aunque hay varios valores, la mayor parte de los pacientes estuvo entre 1 y 4 días hospitalizados, con una disminución progresiva en los valores mayores.
    Esto sugiere estancias hospitalarias relativamente cortas para la mayoría.

Distribución de pruebas, procedimientos y medicamentos

for (col in cat_prue_proced) {
  print(
    ggplot(df, aes_string(x = col, fill = col)) +
      geom_bar() +
      labs(title = paste("Distribución de  la variable ", col), x = col, y = "Frecuencia") +
      theme_minimal()
  )
}
## Warning: The following aesthetics were dropped during statistical transformation: fill.
## ℹ This can happen when ggplot fails to infer the correct grouping structure in
##   the data.
## ℹ Did you forget to specify a `group` aesthetic or to convert a numerical
##   variable into a factor?

## Warning: The following aesthetics were dropped during statistical transformation: fill.
## ℹ This can happen when ggplot fails to infer the correct grouping structure in
##   the data.
## ℹ Did you forget to specify a `group` aesthetic or to convert a numerical
##   variable into a factor?

## Warning: The following aesthetics were dropped during statistical transformation: fill.
## ℹ This can happen when ggplot fails to infer the correct grouping structure in
##   the data.
## ℹ Did you forget to specify a `group` aesthetic or to convert a numerical
##   variable into a factor?

## Warning: The following aesthetics were dropped during statistical transformation: fill.
## ℹ This can happen when ggplot fails to infer the correct grouping structure in
##   the data.
## ℹ Did you forget to specify a `group` aesthetic or to convert a numerical
##   variable into a factor?

## Warning: The following aesthetics were dropped during statistical transformation: fill.
## ℹ This can happen when ggplot fails to infer the correct grouping structure in
##   the data.
## ℹ Did you forget to specify a `group` aesthetic or to convert a numerical
##   variable into a factor?

## Warning: The following aesthetics were dropped during statistical transformation: fill.
## ℹ This can happen when ggplot fails to infer the correct grouping structure in
##   the data.
## ℹ Did you forget to specify a `group` aesthetic or to convert a numerical
##   variable into a factor?

## Warning: The following aesthetics were dropped during statistical transformation: fill.
## ℹ This can happen when ggplot fails to infer the correct grouping structure in
##   the data.
## ℹ Did you forget to specify a `group` aesthetic or to convert a numerical
##   variable into a factor?

La figura muestra la distribución de diferentes variables relacionadas con los procedimientos médicos, las pruebas realizadas y el número de medicamentos administrados durante las hospitalizaciones.

  • Número de procedimientos de laboratorio (num_lab_procedures):
    Esta variable tiene muchas categorías (118), pero se observa que hay una concentración importante en valores entre 40 y 70 procedimientos por paciente. Es decir, la mayoría de los pacientes tuvieron una cantidad intermedia de pruebas de laboratorio, lo que sugiere un nivel de monitoreo moderado durante la hospitalización.

  • Número de procedimientos (num_procedures):
    En este caso, la mayoría de los pacientes tuvo cero o un procedimiento médico. Las frecuencias disminuyen progresivamente a medida que aumenta el número de procedimientos, lo que indica que la intervención médica directa no fue tan alta en la mayoría de los casos.

  • Número de medicamentos (num_medications):
    Hay una clara tendencia a la alta cantidad de medicamentos administrados. Las categorías más frecuentes están entre 10 y 18 medicamentos, lo que podría indicar tratamientos complejos o presencia de múltiples condiciones médicas.

  • Consultas externas (number_outpatient):
    La mayoría de los pacientes no tuvo consultas externas previas a la hospitalización (valor 0). Solo una pequeña proporción tuvo una o más visitas ambulatorias, lo que sugiere que muchos ingresos fueron inesperados o sin seguimiento ambulatorio reciente.

  • Visitas a emergencias (number_emergency):
    Al igual que en el caso anterior, la mayoría de los pacientes no tuvo visitas previas a emergencias antes de ser hospitalizados. Esto puede reforzar la idea de que muchos ingresos fueron por primera atención de una complicación aguda.

  • Consultas internas previas (number_inpatient):
    Se observa que la mayoría no tuvo hospitalizaciones anteriores (valor 0), aunque existe una pequeña proporción que ha sido hospitalizada previamente en múltiples ocasiones, lo que puede reflejar casos más crónicos o severos.

  • Cantidad de diagnósticos (number_diagnoses):
    La mayoría de los pacientes tiene registrados nueve diagnósticos, que es el valor máximo permitido por la base de datos. Esto indica que muchos pacientes presentan múltiples condiciones de salud, lo que puede reflejar la complejidad clínica del grupo.

Diagnósticos principales y secundarios

for (col in cat_diag_princ) {
  print(
    ggplot(df, aes_string(x = col, fill = col)) +
      geom_bar() +
      labs(title = paste("Distribución de  la variable ", col), x = col, y = "Frecuencia") +
      theme_minimal()
  )
}
## Warning: The following aesthetics were dropped during statistical transformation: fill.
## ℹ This can happen when ggplot fails to infer the correct grouping structure in
##   the data.
## ℹ Did you forget to specify a `group` aesthetic or to convert a numerical
##   variable into a factor?

## Warning: The following aesthetics were dropped during statistical transformation: fill.
## ℹ This can happen when ggplot fails to infer the correct grouping structure in
##   the data.
## ℹ Did you forget to specify a `group` aesthetic or to convert a numerical
##   variable into a factor?

## Warning: The following aesthetics were dropped during statistical transformation: fill.
## ℹ This can happen when ggplot fails to infer the correct grouping structure in
##   the data.
## ℹ Did you forget to specify a `group` aesthetic or to convert a numerical
##   variable into a factor?

Esta figura muestra la distribución de los diagnósticos principales (diag_1) y secundarios (diag_2, diag_3) registrados para cada paciente. Las categorías representan grupos de enfermedades, basados en los códigos ICD-9 agrupados por rangos.

  • Diagnóstico principal (diag_1):
    La categoría más frecuente es la 2.0, relacionada con enfermedades del sistema circulatorio. Le sigue la categoría 14.0, que representa los diagnósticos de diabetes (por ejemplo, códigos 250.xx). Esta combinación muestra que muchos pacientes ingresan al hospital con complicaciones cardíacas o directamente por complicaciones derivadas de la diabetes.

  • Segundo diagnóstico (diag_2):
    De nuevo, la categoría 2.0 sobresale por mucho, indicando que muchas personas presentan enfermedades cardiovasculares como condición secundaria. Le siguen las categorías 3.0 (enfermedades del sistema respiratorio) y 14.0 (diabetes), con frecuencias similares. Esto refleja que, en pacientes con múltiples condiciones, es muy común ver esta combinación de enfermedades circulatorias, respiratorias y metabólicas.

  • Tercer diagnóstico (diag_3):
    En este caso, la categoría 2.0 continúa siendo la más común, y la 3.0 le sigue con una frecuencia notable —un poco más de la mitad de la que tiene la categoría 2.0. Esta tendencia refuerza la idea de que las enfermedades del corazón y pulmón son condiciones crónicas recurrentes en pacientes hospitalizados, muchas veces en conjunto con la diabetes.

Resultados de laboratorio

for (col in cat_resultados_lab) {
  print(
    ggplot(df, aes_string(x = col, fill = col)) +
      geom_bar() +
      labs(title = paste("Distribución de  la variable ", col), x = col, y = "Frecuencia") +
      theme_minimal()
  )
}
## Warning: The following aesthetics were dropped during statistical transformation: fill.
## ℹ This can happen when ggplot fails to infer the correct grouping structure in
##   the data.
## ℹ Did you forget to specify a `group` aesthetic or to convert a numerical
##   variable into a factor?

## Warning: The following aesthetics were dropped during statistical transformation: fill.
## ℹ This can happen when ggplot fails to infer the correct grouping structure in
##   the data.
## ℹ Did you forget to specify a `group` aesthetic or to convert a numerical
##   variable into a factor?

Esta figura muestra la distribución de dos variables relacionadas con exámenes clínicos importantes en el control de la diabetes: max_glu_serum (nivel máximo de glucosa en suero) y A1Cresult (resultado del examen de hemoglobina glicosilada).

  • Nivel máximo de glucosa en suero (max_glu_serum):
    La mayoría de los registros se encuentran en la categoría 3.0, que corresponde a “No se realizó el test”. Esto indica que para la gran mayoría de pacientes no se midió el valor máximo de glucosa durante su estancia hospitalaria. Las demás categorías (0.0, 1.0, 2.0) tienen frecuencias muy bajas, lo que sugiere que cuando sí se hace la prueba, es en muy pocos casos.

  • Resultado del examen A1C (A1Cresult):
    Al igual que en la variable anterior, la categoría más frecuente es la 3.0, lo que también significa que no se realizó el test de hemoglobina glicosilada. Las otras tres categorías (0.0: “normal”, 1.0: “>7”, 2.0: “>8”) están presentes pero con frecuencias mucho menores. Esto puede implicar que el seguimiento a largo plazo del control glucémico no se hace de manera sistemática en los pacientes hospitalizados.

Medicamentos administrados durante la estancia

for (col in cat_meds) {
  print(
    ggplot(df, aes_string(x = col, fill = col)) +
      geom_bar() +
      labs(title = paste("Distribución de  la variable ", col), x = col, y = "Frecuencia") +
      theme_minimal()
  )
}
## Warning: The following aesthetics were dropped during statistical transformation: fill.
## ℹ This can happen when ggplot fails to infer the correct grouping structure in
##   the data.
## ℹ Did you forget to specify a `group` aesthetic or to convert a numerical
##   variable into a factor?

## Warning: The following aesthetics were dropped during statistical transformation: fill.
## ℹ This can happen when ggplot fails to infer the correct grouping structure in
##   the data.
## ℹ Did you forget to specify a `group` aesthetic or to convert a numerical
##   variable into a factor?

## Warning: The following aesthetics were dropped during statistical transformation: fill.
## ℹ This can happen when ggplot fails to infer the correct grouping structure in
##   the data.
## ℹ Did you forget to specify a `group` aesthetic or to convert a numerical
##   variable into a factor?

## Warning: The following aesthetics were dropped during statistical transformation: fill.
## ℹ This can happen when ggplot fails to infer the correct grouping structure in
##   the data.
## ℹ Did you forget to specify a `group` aesthetic or to convert a numerical
##   variable into a factor?

## Warning: The following aesthetics were dropped during statistical transformation: fill.
## ℹ This can happen when ggplot fails to infer the correct grouping structure in
##   the data.
## ℹ Did you forget to specify a `group` aesthetic or to convert a numerical
##   variable into a factor?

## Warning: The following aesthetics were dropped during statistical transformation: fill.
## ℹ This can happen when ggplot fails to infer the correct grouping structure in
##   the data.
## ℹ Did you forget to specify a `group` aesthetic or to convert a numerical
##   variable into a factor?

## Warning: The following aesthetics were dropped during statistical transformation: fill.
## ℹ This can happen when ggplot fails to infer the correct grouping structure in
##   the data.
## ℹ Did you forget to specify a `group` aesthetic or to convert a numerical
##   variable into a factor?

## Warning: The following aesthetics were dropped during statistical transformation: fill.
## ℹ This can happen when ggplot fails to infer the correct grouping structure in
##   the data.
## ℹ Did you forget to specify a `group` aesthetic or to convert a numerical
##   variable into a factor?

## Warning: The following aesthetics were dropped during statistical transformation: fill.
## ℹ This can happen when ggplot fails to infer the correct grouping structure in
##   the data.
## ℹ Did you forget to specify a `group` aesthetic or to convert a numerical
##   variable into a factor?

## Warning: The following aesthetics were dropped during statistical transformation: fill.
## ℹ This can happen when ggplot fails to infer the correct grouping structure in
##   the data.
## ℹ Did you forget to specify a `group` aesthetic or to convert a numerical
##   variable into a factor?

## Warning: The following aesthetics were dropped during statistical transformation: fill.
## ℹ This can happen when ggplot fails to infer the correct grouping structure in
##   the data.
## ℹ Did you forget to specify a `group` aesthetic or to convert a numerical
##   variable into a factor?

## Warning: The following aesthetics were dropped during statistical transformation: fill.
## ℹ This can happen when ggplot fails to infer the correct grouping structure in
##   the data.
## ℹ Did you forget to specify a `group` aesthetic or to convert a numerical
##   variable into a factor?

## Warning: The following aesthetics were dropped during statistical transformation: fill.
## ℹ This can happen when ggplot fails to infer the correct grouping structure in
##   the data.
## ℹ Did you forget to specify a `group` aesthetic or to convert a numerical
##   variable into a factor?

## Warning: The following aesthetics were dropped during statistical transformation: fill.
## ℹ This can happen when ggplot fails to infer the correct grouping structure in
##   the data.
## ℹ Did you forget to specify a `group` aesthetic or to convert a numerical
##   variable into a factor?

## Warning: The following aesthetics were dropped during statistical transformation: fill.
## ℹ This can happen when ggplot fails to infer the correct grouping structure in
##   the data.
## ℹ Did you forget to specify a `group` aesthetic or to convert a numerical
##   variable into a factor?

## Warning: The following aesthetics were dropped during statistical transformation: fill.
## ℹ This can happen when ggplot fails to infer the correct grouping structure in
##   the data.
## ℹ Did you forget to specify a `group` aesthetic or to convert a numerical
##   variable into a factor?

## Warning: The following aesthetics were dropped during statistical transformation: fill.
## ℹ This can happen when ggplot fails to infer the correct grouping structure in
##   the data.
## ℹ Did you forget to specify a `group` aesthetic or to convert a numerical
##   variable into a factor?

## Warning: The following aesthetics were dropped during statistical transformation: fill.
## ℹ This can happen when ggplot fails to infer the correct grouping structure in
##   the data.
## ℹ Did you forget to specify a `group` aesthetic or to convert a numerical
##   variable into a factor?

## Warning: The following aesthetics were dropped during statistical transformation: fill.
## ℹ This can happen when ggplot fails to infer the correct grouping structure in
##   the data.
## ℹ Did you forget to specify a `group` aesthetic or to convert a numerical
##   variable into a factor?

## Warning: The following aesthetics were dropped during statistical transformation: fill.
## ℹ This can happen when ggplot fails to infer the correct grouping structure in
##   the data.
## ℹ Did you forget to specify a `group` aesthetic or to convert a numerical
##   variable into a factor?

## Warning: The following aesthetics were dropped during statistical transformation: fill.
## ℹ This can happen when ggplot fails to infer the correct grouping structure in
##   the data.
## ℹ Did you forget to specify a `group` aesthetic or to convert a numerical
##   variable into a factor?

Esta figura presenta la distribución de diferentes medicamentos utilizados en pacientes hospitalizados con diagnóstico de diabetes.

  • En general, la mayoría de los medicamentos individuales (como metformin, glimepiride, glyburide, pioglitazone, entre otros) tienen como categoría más común el valor 1.0, lo que indica que la medicación no cambió durante la estancia. Es decir, los pacientes que ya estaban tomando estos medicamentos continuaron con ellos.

  • Las categorías 2.0 (medicación añadida) y 3.0 (medicación discontinuada) aparecen con menor frecuencia. En la mayoría de los casos, la categoría 0.0 (medicación nunca utilizada) tiene una baja frecuencia, excepto en medicamentos poco comunes, como acetohexamide, tolazamide o combinaciones poco frecuentes.

  • En los medicamentos combinados (como glyburide-metformin, glipizide-metformin, metformin-pioglitazone), se observa que la mayoría de los pacientes no recibieron estas combinaciones durante la hospitalización. Esto puede deberse a que estas terapias son más comunes en tratamientos ambulatorios que en contextos agudos.

  • Una excepción interesante es la insulina, donde las frecuencias están distribuidas entre todas las categorías. Esto indica que sí hubo ajustes importantes en su administración, probablemente en respuesta a las necesidades clínicas inmediatas de los pacientes hospitalizados.

Control del tratamiento para la diabetes

for (col in cat_control_tratamiento) {
  print(
    ggplot(df, aes_string(x = col, fill = col)) +
      geom_bar() +
      labs(title = paste("Distribución de  la variable ", col), x = col, y = "Frecuencia") +
      theme_minimal()
  )
}
## Warning: The following aesthetics were dropped during statistical transformation: fill.
## ℹ This can happen when ggplot fails to infer the correct grouping structure in
##   the data.
## ℹ Did you forget to specify a `group` aesthetic or to convert a numerical
##   variable into a factor?

## Warning: The following aesthetics were dropped during statistical transformation: fill.
## ℹ This can happen when ggplot fails to infer the correct grouping structure in
##   the data.
## ℹ Did you forget to specify a `group` aesthetic or to convert a numerical
##   variable into a factor?

Esta figura presenta la distribución de dos variables relacionadas con el control del tratamiento de pacientes hospitalizados con diagnóstico de diabetes.

  • En el gráfico izquierdo, correspondiente a la variable change, se observa que la mayoría de los pacientes presentan un valor de 1.0, lo que indica que hubo un cambio en la medicación durante la hospitalización. Este comportamiento sugiere que, en muchos casos, el tratamiento fue ajustado, probablemente en respuesta a evaluaciones médicas o complicaciones agudas. No obstante, una cantidad considerable de pacientes también se mantuvo con su tratamiento sin cambios (0.0), lo que podría reflejar condiciones estables o seguimiento de un protocolo ya establecido.

  • En el gráfico derecho, correspondiente a la variable diabetesMed, se destaca que la mayoría de los pacientes tienen un valor de 1.0, lo que significa que recibieron medicación para la diabetes durante su estancia hospitalaria. En contraste, una proporción menor de pacientes (0.0) no recibió medicación, lo cual puede deberse a múltiples factores, como estadías cortas, control dietético, o decisiones clínicas específicas. La predominancia del uso de medicamentos refleja la importancia del tratamiento farmacológico en el manejo hospitalario de la diabetes.

Ambas variables reflejan la dinámica del tratamiento médico en contextos hospitalarios, evidenciando tanto la alta tasa de intervención como la adaptación del manejo clínico según las condiciones del paciente.

Distribución de la variable objetivo (readmisión)

for (col in cat_objetivo) {
  print(
    ggplot(df, aes_string(x = col, fill = col)) +
      geom_bar() +
      labs(title = paste("Distribución de  la variable ", col), x = col, y = "Frecuencia") +
      theme_minimal()
  )
}
## Warning: The following aesthetics were dropped during statistical transformation: fill.
## ℹ This can happen when ggplot fails to infer the correct grouping structure in
##   the data.
## ℹ Did you forget to specify a `group` aesthetic or to convert a numerical
##   variable into a factor?

El gráfico revela que la mayoría de los pacientes no fueron readmitidos (2.0), con una frecuencia superior a 50.000 casos. En segundo lugar se encuentran los pacientes que sí fueron readmitidos, pero después de 30 días (1.0), y finalmente, con una frecuencia mucho menor, los pacientes que fueron readmitidos antes de 30 días (0.0).

Análisis con cruces de variables

En esta parte, se cruzan diferentes variables, para determinar si existe alguna relación que se pueda determinar visualmente.

En primer lugar, se cruzan todas las variables numéricas.

# Definir las columnas de interés
cols_interes <- c("time_in_hospital", "num_lab_procedures", "num_procedures", 
                 "num_medications", "number_outpatient", "number_emergency", 
                 "number_inpatient", "number_diagnoses")

# Crear todas las combinaciones posibles de pares de variables numéricas
combis <- expand.grid(x = cols_interes, y = cols_interes, stringsAsFactors = FALSE)

# Generar un solo data frame con todas las combinaciones y sus puntos
graficos <- combis %>%
  rowwise() %>%
  mutate(
    plot = list(
      ggplot(df, aes_string(x = x, y = y)) +
        geom_point(alpha = 0.6) +
        theme_minimal() +
        labs(x = x, y = y)
    )
  )

# Mostrar todos los gráficos juntos
library(gridExtra)
grid.arrange(grobs = graficos$plot, ncol = length(cols_interes))

Como se observó anteriormente en la matriz de correlación, no existe alta correlación entre variables de tipo numerica.

Asimimo, se cruza cada vaariable numérica contra la variable ‘readmitted’.

graficar_num_vs_cat <- function(df, var_cat){
  # Detectar columnas numéricas automáticamente
  num_vars <- names(df)[sapply(df, is.numeric)]
  
  plots <- lapply(num_vars, function(var_num) {
    ggplot(df, aes_string(x = var_cat, y = var_num, fill = var_cat)) +
      geom_boxplot(alpha = 0.7) +
      labs(title = paste(var_num, "vs", var_cat),
           x = var_cat, y = var_num) +
      theme_minimal() +
      theme(legend.position = "none")
  })
  
  grid.arrange(grobs = plots, ncol = 2)  
}

# Ejemplo de uso
graficar_num_vs_cat(iris, "Species")

A simple vista no se observa alguna relación o patrón entre variables para determinar si una persona fue readmitida o no.

Y por último, se combina cada variable categórica con la cariables objetivo: ‘readmitted’.

categorical_vars <- df %>%
  select(where(~ is.character(.) | is.factor(.))) %>%
  names() %>%
  setdiff("readmitted")

for (col in categorical_vars) {
  p <- ggplot(df, aes(x = !!sym(col), fill = readmitted)) +
    geom_bar(position = "dodge") +
    labs(title = paste(col, "vs readmitted"),
         x = col,
         y = "Count") +
    theme_minimal() +
    theme(axis.text.x = element_text(angle = 45, hjust = 1),
          legend.position = "right")
  
  print(p)
}

Con ayuda de estas gráficas, se observa un claro desbalance de clases, pues en su mayoría domina la categoría 2.0, que indica que el paciente no fue readmitido.