1 NaN values

## 2018- 2019
dat1 <- data.frame(dat)[c(1:193),]

## 2019 - 2021
dat2 <- data.frame(dat)[c(194:dim(dat)[1]),]

## All the data, 2018 - 2021
dat <- data.frame(dat)
english_col_names <- c(
  "ID", "Gender", "Personal History", "Date of Birth", "Date of Admission",
  "Age (Months)", "Date of Discharge", "Rotavirus Vaccination", "Breastfeeding",
  "Epidemiological Background", "Suspected Food", "Malnutrition", "Reason for Admission",
  "Clinical Days to Admission", "Heart Rate", "Systolic Blood Pressure", "Diastolic Blood Pressure",
  "Fever", "Peak Fever", "Vomiting", "Vomiting per Day", "Antiemetics", "Diarrhea", "Stool per Day",
  "Pathologic Products", "Blood in Stool", "Dehydration", "Dehydration Rate", "Quick Intravenous Rehydration",
  "Etiology", "Complications", "Acidosis", "Hyponatremia", "Renal Failure (KDiGO Estimate)",
  "pH", "Sodium", "Potassium", "Bicarbonate", "Base Excess", "Chlorine", "Creatinine", "Urea",
  "AST (Aspartate Aminotransferase)", "ALT (Alanine Aminotransferase)", "Albumin", "C-reactive Protein",
  "Hemoglobin", "Leukocytes", "Neutrophils", "Lymphocytes", "Platelets", "Etiology3", "Etiology2"
)

colnames(dat1) <- english_col_names
colnames(dat2) <- english_col_names
colnames(dat) <- english_col_names

1.0.1 dat 1 2018 - 2019

vis_miss(dat1, sort_miss = TRUE, show_perc = TRUE) + 
  theme(axis.text.x = element_text(angle = 90))

1.0.2 dat 1 2020 - 2021

vis_miss(dat2, sort_miss = TRUE, show_perc = TRUE) + 
  theme(axis.text.x = element_text(angle = 90))

1.0.3 dat all

vis_miss(dat, sort_miss = TRUE, show_perc = TRUE) + 
  theme(axis.text.x = element_text(angle = 90))

1.1 Eliminamos Albúmina

dat1_al <- subset(dat1, select=-c(Albumin))
dat2_al <- subset(dat2, select=-c(Albumin))
dat_al <- subset(dat, select=-c(Albumin))

1.1.1 dat 1 2018 - 2019 no Albumina

vis_miss(dat1_al, sort_miss = TRUE, show_perc = TRUE) + 
  theme(axis.text.x = element_text(angle = 90))

1.1.2 dat 1 2020 - 2021 no Albumina

vis_miss(dat2_al, sort_miss = TRUE, show_perc = TRUE) + 
  theme(axis.text.x = element_text(angle = 90))

1.1.3 dat all no Albumina

vis_miss(dat_al, sort_miss = TRUE, show_perc = TRUE) + 
  theme(axis.text.x = element_text(angle = 90))

1.2 Eliminamos los factores “con alto % de faltantes y a posteriori”, variable para realizar el modelo de clasificación

dat1_post <- subset(dat1_al, select = -c(`Breastfeeding`, `ID`, `Rotavirus Vaccination`, `Date of Admission`, `Date of Discharge`, `Antiemetics`, `Complications`))
dat2_post <- subset(dat2_al, select = -c(`Breastfeeding`, `ID`, `Rotavirus Vaccination`, `Date of Admission`, `Date of Discharge`, `Antiemetics`, `Complications`))
dat_post <- subset(dat_al, select = -c(`Breastfeeding`, `ID`, `Rotavirus Vaccination`, `Date of Admission`, `Date of Discharge`, `Antiemetics`, `Complications`))

1.2.1 dat 1 2018 - 2019 % and a posteriori

vis_miss(dat1_post, sort_miss = TRUE, show_perc = TRUE) + 
  theme(axis.text.x = element_text(angle = 90))

1.2.2 dat 1 2020 - 2021 % and a posteriori

vis_miss(dat2_post, sort_miss = TRUE, show_perc = TRUE) + 
  theme(axis.text.x = element_text(angle = 90))

1.2.3 dat all % and a posteriori

vis_miss(dat_post, sort_miss = TRUE, show_perc = TRUE) + 
  theme(axis.text.x = element_text(angle = 90))

2 Basic Descriptive Analysis

A continuación se muestran diveras proporciones respecto a diferentes variables en el dataset:

Gender
Variables Freq
Mujer 44.01295
Varon 55.98705
Hyponatremia
Variables Freq
No 74.58746
Si 25.41254
Dehydration
Variables Freq
No 39.61039
Si 60.38961
Pacientes cada año
Variables Freq
2018 32.68608
2019 30.09709
2020 10.35599
2021 26.86084

Distribución de las diferentes Etiologías:

Etiology Amount
Bacterium 76
Unknown 115
Negative 4
Virus 114
Total 309

Distribución de las diferentes Etiologías en función del año:

Distribución de los pacientes en función del tipo de Etiología

Ingresos en función de la Edad:

Ingreso en función de la edad considerando solo Bacterias y Virus:

# Some more graphs

# Common color palette for both plots
library(ggplot2)
library(ggpubr)

# Common color palette for both plots
common_fill_cols <- c("#FF6B6B", "#FFD166", "#06D6A0", "#118AB2")

lower_limit_EB <- -2
upper_limit_EB <- 2
# Create a scatter plot for Age vs. Base Excess
scatter_plot <- ggplot(dat, aes(y =`Age (Months)`, x =`Base Excess`, group=`Etiology2`, color=`Etiology2`)) +
  geom_point() + 
  labs(y="Age", x="Base Excess") +
  scale_color_manual(values=common_fill_cols, name="Etiology")   # Use the common color palette and set the legend name

# Create a density plot for Base Excess
density_plot <- ggplot(dat, aes(x=`Base Excess`, group=`Etiology2`, fill=`Etiology2`)) +
  geom_density(alpha=0.7) +
  # Add vertical lines for healthy patient limits
  geom_vline(xintercept = c(lower_limit_EB, upper_limit_EB), color = "blue", linetype = "dashed") +
  # Set x-axis label
  xlab("Base Excess") +
  scale_fill_manual(values=common_fill_cols, name="Etiology") 

# Combine the plots into a grid
combined_plots <- ggarrange(density_plot, scatter_plot,
          common.legend = TRUE, legend = "bottom")
## Warning: Removed 34 rows containing non-finite values (`stat_density()`).
## Removed 34 rows containing non-finite values (`stat_density()`).
## Warning: Removed 34 rows containing missing values (`geom_point()`).
combined_plots

# Common color palette for both plots
common_fill_cols <- c("#FF6B6B", "#FFD166", "#06D6A0", "#118AB2")

lower_limit_pH <- 7.35
upper_limit_pH <- 7.45

# Create a scatter plot for Age vs. pH
scatter_plot <- ggplot(dat, aes(y =`Age (Months)`, x =`pH`, group=`Etiology2`, color=`Etiology2`)) +
  geom_point() + 
  labs(y="Age", x="pH") +
  scale_color_manual(values=common_fill_cols, name="Etiology")   # Use the common color palette and set the legend name

# Create a density plot for pH
density_plot <- ggplot(dat, aes(x=`pH`, group=`Etiology2`, fill=`Etiology2`)) +
  geom_density(alpha=0.7) +
  # Add vertical lines for healthy patient limits
  geom_vline(xintercept = c(lower_limit_pH, upper_limit_pH), color = "blue", linetype = "dashed") +
  # Set x-axis label
  xlab("pH") +
  scale_fill_manual(values=common_fill_cols, name="Etiology") 

# Combine the plots into a grid
combined_plots <- ggarrange(density_plot, scatter_plot,
          common.legend = TRUE, legend = "bottom")
## Warning: Removed 31 rows containing non-finite values (`stat_density()`).
## Removed 31 rows containing non-finite values (`stat_density()`).
## Warning: Removed 31 rows containing missing values (`geom_point()`).
combined_plots

2.1 Modelo

load("../datasets/Final_DatasetENG.RData")

2.1.1 Error de Clasificación

A continuación se muestra el error producido por cada modelo realizado:

A continuación se muestra la puntuación producida por cada modelo realizado

Aislamos el Modelo ROJO y AMARILLO

Porcentaje de Varianza Explicada Tipo de Procedimiento Usado Error Absoluto Cantidad de Pacientes estudiados Ratio Bacteria/Virus Nº Variables Usadas Nº Variables Numericas Usadas
Amarillo 90 PROC_2 12.2272727272727 111 0.982142857142857 23 5
Rojo 70 PROC_4 9.15384615384616 67 0.810810810810811 23 5
Porcentaje de Varianza Explicada Tipo de Procedimiento Usado Error Absoluto Cantidad de Pacientes estudiados Ratio Bacteria/Virus Nº Variables Usadas Nº Variables Numericas Usadas
Mejor Error de clasificacion 80 PROC_1 8.5 52 0.925925925925926 38 20
Mejor Puntuación 80 PROC_3 9.3 50 1 38 20

Consideramos el modelo amarillo al presentar un gran número de pacientes.

2.1.2 Modelo AMARILLO

Las 5 variables númericas usadas en el modelo amarillo son:

La matriz de confusión obtenida con el modelo AMARILLO incluído en la app es la siguiente:

  • Acierto: 87.64 %

    • Acierto Bacterium: 81.81 %

    • Acierto Virus: 93.33 %

  • Fallo: 12.35 %

    • Fallo Bacterium: 18.18%

    • Fallo Virus: 6.67 %

3 APP

La aplicación se encuentra en el siguiente enlace: https://gonzaloaris.shinyapps.io/AppBacteriaVirus/.

4 Conclusión

La cantidad de pacientes utilizados en el mejor modelo son 111. De este modelo 89 fueron aquellos que se encargaron de entrenarlo y se validó con 22 pacientes obteniendo así un error medio del 12.23 % a la hora de clasificar pacientes víricos y bacterianos. Este error medio es el resultado de clasificar 100 veces 89 pacientes de los 111 obtenidos de forma aleatoria.

dim(dat[dat$Etiology2 == "Virus" | dat$Etiology2 == "Bacterium",])
## [1]  0 53

En total existen 190 pacientes catalogados como víricos y bacterianos. Si quitamos de estos 190 pacientes los 89 utilizados para entrenar el modelo queda un total de 101 pacientes, los cuales serán usados para validarlo. De estos 101 pacientes 22 tienen los datos completos y habrá que inputar datos a 79 con aquellos 22 pacientes que tienen datos completos.

La inputación de datos será llevada a cabo por el método Gower ed la siguiente forma: [https://rpubs.com/garisj98/DataInputGowerDistance]

La matriz de confusión generada utilizando el modelo AMARILLO que se entrena con 89 pacientes es:

  • Acierto: 94.05 %

    • Acierto Bacterium: 90.62 %

    • Acierto Virus: 95.7 %

  • Fallo: 5.95 %

    • Fallo Bacterium: 9.38 %

    • Fallo Virus: 4.3 %

[Se están teniendo en cuenta los 79 pacientes con datos inputados y los 22 con datos completos, en total 101 pacientes.]