Nombre del dataset:
diabetic_data.csv
Número de instancias: 101,766
Número de variables: 47
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:
A continuación se describen las variables presentes en el dataset
diabetic_data.csv, organizadas por categorías:
| Variable | Tipo | Descripción |
|---|---|---|
encounter_id |
Numérica | Identificador único del encuentro hospitalario (visita). |
patient_nbr |
Numérica | Identificador único del paciente. |
| 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. |
| 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. |
| 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. |
| 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. |
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
| 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 | Tipo | Descripción |
|---|---|---|
readmitted |
Categórica | Indica si el paciente fue readmitido y cuándo. Valores:
<30, >30, No. |
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")
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
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.
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.
# 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
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.
# 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
# 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)
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.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.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.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.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.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.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.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.# 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)
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:
num_medications,
num_lab_procedures, number_emergency,
number_inpatient y number_outpatient
presentaban numerosos outliers alejados del resto de los
datos.# 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:
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.number_outpatient con
time_in_hospital (0.00) o num_lab_procedures
(-0.03) muestran prácticamente nula relación.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.
# 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.
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.
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.
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.
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.
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.
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.
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.
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).
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.