Análisis Diabetes

Author

Brandon Martinez

Published

Invalid Date

Introducción

En este análisis, exploraremos el dataset de diabetes, enfocándonos en la limpieza de datos, preprocesamiento y visualizaciones iniciales.

Datos

Comencemos cargando los paquetes necesarios y el dataset.

Code
#| label: cargar-paquetes
#| message: false
#| include: false

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
Code
library(ggplot2)
library(plotly)

Adjuntando el paquete: 'plotly'
The following object is masked from 'package:ggplot2':

    last_plot
The following object is masked from 'package:stats':

    filter
The following object is masked from 'package:graphics':

    layout
Code
library(reshape2)
library(tidyverse)
── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
✔ forcats   1.0.0     ✔ stringr   1.5.1
✔ lubridate 1.9.3     ✔ tibble    3.2.1
✔ purrr     1.0.2     ✔ tidyr     1.3.1
✔ readr     2.1.5     
── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
✖ plotly::filter() masks dplyr::filter(), stats::filter()
✖ dplyr::lag()     masks stats::lag()
ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
Code
#| output: true

diabetes <- read.csv('diabetes.csv')

Limpieza y Preprocesamiento de Datos Realizamos algunos pasos básicos de limpieza y preprocesamiento de datos, incluyendo el manejo de valores faltantes y la creación de nuevas variables

Code
# Limpiar los datos
diabetes <- diabetes %>%
  filter(Glucose != 0, BloodPressure != 0, BMI != 0) %>%
  mutate(SkinThickness = ifelse(SkinThickness == 0, mean(SkinThickness, na.rm = TRUE), SkinThickness)) %>%
  # Verificar si la columna Insulin existe antes de usarla
  mutate(InsulinKnown = ifelse("Insulin" %in% names(.), ifelse(Insulin != 0, 1, 0), NA)) %>%
  select(Pregnancies, Glucose, BloodPressure, SkinThickness, BMI, 
         DiabetesPedigreeFunction, Age, InsulinKnown, Outcome)

# Dimensiones de los datos y valores faltantes
data_summary <- list(
  dimensions = dim(diabetes),
  missing_values = sum(is.na(diabetes)),
  duplicated_rows = sum(duplicated(diabetes))
)

# Mostrar el resumen de los datos
data_summary
$dimensions
[1] 768   9

$missing_values
[1] 0

$duplicated_rows
[1] 0
Code
names(diabetes)
[1] "Pregnancies"              "Glucose"                 
[3] "BloodPressure"            "SkinThickness"           
[5] "BMI"                      "DiabetesPedigreeFunction"
[7] "Age"                      "InsulinKnown"            
[9] "Outcome"                 

Análisis Exploratorio de Datos Distribución del Resultado {.smaller} Comenzamos visualizando la distribución de la variable de resultado.

Code

outcome_count <- diabetes %>%
  count(Outcome) %>%
  rename(Outcome = Outcome, count = n)

fig <- plot_ly(outcome_count, labels = ~Outcome, values = ~count, type = 'pie', 
               marker = list(colors = c('#FECB52', 'red'))) %>%
  layout(title = 'Outcome', height = 400, width = 400)
## Warning: Specifying width/height in layout() is now deprecated.
## Please specify in ggplotly() or plot_ly()
fig

Distribución de la variable Outcome

Histogramas de Variables {.smaller} Exploramos la distribución de las otras variables en el dataset utilizando histogramas

Code
#| label: histogramas
#| fig-cap: "Histogramas de Tres Variables Seleccionadas"
#| fig-alt: |
#|   Histogramas que muestran la distribución variables.

library(tidyverse)

# Seleccionar las variables numéricas del dataset, excluyendo Outcome
numeric_vars <- diabetes %>%
  select(where(is.numeric)) %>%
  select(-Outcome)

# Seleccionar las tres variables específicas
selected_vars <- c("BloodPressure", "DiabetesPedigreeFunction", "Age")

# Filtrar el dataset para las tres variables seleccionadas
selected_data <- diabetes %>%
  select(all_of(selected_vars)) %>%
  pivot_longer(cols = everything(), names_to = "variable", values_to = "value")

# Crear histogramas para las variables seleccionadas
ggplot(selected_data, aes(x = value)) +
  geom_histogram(bins = 30, fill = "skyblue", color = "black") +
  facet_wrap(~variable, scales = "free_x") +
  theme_minimal() +
  labs(title = "Histogramas de Tres Variables Seleccionadas", x = NULL, y = "Frecuencia")

Matriz de Correlación {.smaller} Finalmente, visualizamos la correlación entre las variables usando un mapa de calor.

Code
# Verificar el tipo de cada columna en el dataframe
sapply(diabetes, class)
             Pregnancies                  Glucose            BloodPressure 
               "integer"                "integer"                "integer" 
           SkinThickness                      BMI DiabetesPedigreeFunction 
               "integer"                "numeric"                "numeric" 
                     Age             InsulinKnown                  Outcome 
               "integer"                "numeric"                "integer" 
Code
#| label: matriz-correlacion
#| fig-cap: "Matriz de Correlación"
#| fig-alt: |
#|   Un mapa de calor que muestra la correlación entre las variables numéricas en el dataset.

library(tidyverse)
library(reshape2)  # Para la función melt

# Seleccionar solo las columnas numéricas
numeric_vars <- diabetes %>%
  select(Pregnancies, Glucose, BloodPressure, SkinThickness, BMI, DiabetesPedigreeFunction, Age)

# Calcular la matriz de correlación
cor_mat <- cor(numeric_vars, use = "complete.obs")

# Convertir la matriz a formato largo para ggplot
cor_mat_long <- melt(cor_mat)

# Crear el mapa de calor
ggplot(cor_mat_long, aes(x = Var1, y = Var2, fill = value)) +
  geom_tile() +
  scale_fill_gradient2(low = "blue", high = "red", mid = "white", midpoint = 0, limit = c(-1, 1)) +
  theme_minimal() +
  labs(title = "Matriz de Correlación", x = NULL, y = NULL, fill = "Correlación") +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

Agrupación de Edades

Code
#| label: age-grouping


# Crear grupos de edades
bins <- c(20, 30, 40, 50, 60, 70, Inf)
labels <- c('20-29', '30-39', '40-49', '50-59', '60-69', '70 +')
diabetes <- diabetes %>%
  mutate(AgeGroup = cut(Age, breaks = bins, labels = labels, right = FALSE))

# Ver la distribución de las edades en cada grupo
table(diabetes$AgeGroup)

20-29 30-39 40-49 50-59 60-69  70 + 
  396   165   118    57    29     3 

analisis estadistico

Code
#| label: distribution-analysis


# Resumen estadístico de las variables por grupo de edad
pivot_table <- diabetes %>%
  group_by(AgeGroup) %>%
  summarise(
    Glucose_Mean = mean(Glucose, na.rm = TRUE),
    BloodPressure_Mean = mean(BloodPressure, na.rm = TRUE),
    BMI_Mean = mean(BMI, na.rm = TRUE)
  )

# Mostrar el resumen
pivot_table
# A tibble: 6 × 4
  AgeGroup Glucose_Mean BloodPressure_Mean BMI_Mean
  <fct>           <dbl>              <dbl>    <dbl>
1 20-29            115.               68.8     32.0
2 30-39            126.               73.4     32.7
3 40-49            126.               76.9     34.6
4 50-59            140.               79.8     31.9
5 60-69            139.               78.3     29.8
6 70 +             133.               75       26  

Visualización de la Distribución

Code
#| label: distribution-visualization
#| fig-cap: "Distribución de Glucosa, Presión Arterial y IMC por Grupo de Edad"
#| fig-alt: "Gráficos de caja para Glucosa, Presión Arterial y IMC en diferentes grupos de edad"


# Visualización con boxplot para cada variable en cada grupo de edad
ggplot(diabetes, aes(x = AgeGroup)) +
  geom_boxplot(aes(y = Glucose), fill = "lightblue") +
  labs(title = "Distribución de Glucosa por Grupo de Edad", x = "Grupo de Edad", y = "Glucosa") +
  theme_minimal()

Code
ggplot(diabetes, aes(x = AgeGroup)) +
  geom_boxplot(aes(y = BloodPressure), fill = "lightgreen") +
  labs(title = "Distribución de Presión Arterial por Grupo de Edad", x = "Grupo de Edad", y = "Presión Arterial") +
  theme_minimal()

Code
ggplot(diabetes, aes(x = AgeGroup)) +
  geom_boxplot(aes(y = BMI), fill = "lightcoral") +
  labs(title = "Distribución de IMC por Grupo de Edad", x = "Grupo de Edad", y = "IMC") +
  theme_minimal()

Code
library(ggplot2)
library(dplyr)

# Filtrar para los grupos de edad 20-29 y 30-39
selected_age_groups <- diabetes %>%
  filter(AgeGroup %in% c('20-29', '30-39'))

# Visualizar la distribución de DiabetesPedigreeFunction en estos grupos
ggplot(selected_age_groups, aes(x = DiabetesPedigreeFunction, fill = AgeGroup)) +
  geom_histogram(position = "dodge", bins = 30, alpha = 0.7) +
  scale_fill_manual(values = c("lightblue", "lightgreen"), 
                    labels = c('20-29', '30-39')) +
  theme_minimal() +
  labs(title = "Distribución de DiabetesPedigreeFunction por Grupo de Edad (20-29 y 30-39)",
       x = "DiabetesPedigreeFunction",
       y = "Frecuencia",
       fill = "Grupo de Edad")

Code
# Gráfico de densidad de DiabetesPedigreeFunction por Grupo de Edad
ggplot(selected_age_groups, aes(x = DiabetesPedigreeFunction, color = AgeGroup, fill = AgeGroup)) +
  geom_density(alpha = 0.3) +
  scale_color_manual(values = c("blue", "green"), 
                     labels = c('20-29', '30-39')) +
  scale_fill_manual(values = c("lightblue", "lightgreen"), 
                    labels = c('20-29', '30-39')) +
  theme_minimal() +
  labs(title = "Distribución de Densidad de DiabetesPedigreeFunction por Grupo de Edad (20-29 y 30-39)",
       x = "DiabetesPedigreeFunction",
       y = "Densidad",
       color = "Grupo de Edad",
       fill = "Grupo de Edad")

Code
#| label: analisis-distribucion-diabetes

#| fig-width: 10
#| fig-asp: 0.618
#| fig-alt: "Histograma y gráfico de densidad de DiabetesPedigreeFunction"
#| fig-cap: "Distribución y densidad de DiabetesPedigreeFunction para los grupos de edad y edades específicas."



# Filtrar los datos para los grupos de edad 20-29 y 30-39
diabetes_filtered <- diabetes %>% filter(AgeGroup %in% c('20-29', '30-39'))

# Filtrar los datos para edades específicas (no agrupadas) pero en el mismo dataframe
diabetes_specific_ages <- diabetes %>% filter(Age >= 20 & Age <= 39)

# Combinar ambos datasets
diabetes_combined <- bind_rows(
  mutate(diabetes_filtered, Type = "Grupo de Edad"),
  mutate(diabetes_specific_ages, Type = "Edad Específica")
)

# Histograma de DiabetesPedigreeFunction para los grupos de edad y edades específicas
ggplot(diabetes_combined, aes(x = DiabetesPedigreeFunction, fill = Type)) +
  geom_histogram(position = "dodge", bins = 30, alpha = 0.7) +
  scale_fill_manual(values = c("lightblue", "lightgreen"), labels = c("Grupo de Edad", "Edad Específica")) +
  theme_minimal() +
  labs(title = 'Distribución de DiabetesPedigreeFunction por Grupo de Edad y Edad Específica',
       x = 'DiabetesPedigreeFunction',
       y = 'Frecuencia',
       fill = 'Tipo')

Code
# Gráfico de densidad de DiabetesPedigreeFunction para los grupos de edad y edades específicas
ggplot(diabetes_combined, aes(x = DiabetesPedigreeFunction, color = Type, fill = Type)) +
  geom_density(alpha = 0.3) +
  scale_color_manual(values = c("blue", "green"), labels = c("Grupo de Edad", "Edad Específica")) +
  scale_fill_manual(values = c("lightblue", "lightgreen"), labels = c("Grupo de Edad", "Edad Específica")) +
  theme_minimal() +
  labs(title = 'Distribución de Densidad de DiabetesPedigreeFunction por Grupo de Edad y Edad Específica',
       x = 'DiabetesPedigreeFunction',
       y = 'Densidad',
       color = 'Tipo',
       fill = 'Tipo')

Code
#| label: resumen-estadistico-edad


#| fig-width: 7
#| fig-asp: 0.618
#| fig-alt: "Resumen estadístico de DiabetesPedigreeFunction por edad"
#| fig-cap: "Resumen estadístico de la función DiabetesPedigreeFunction para personas de 20 a 39 años, agrupado por edad."


library(dplyr)
library(knitr)

# Filtrar los datos para las edades específicas entre 20 y 39 años
diabetes_filtered <- diabetes %>%
  filter(Age >= 20 & Age <= 39)

# Resumen estadístico para DiabetesPedigreeFunction por edad
summary_stats <- diabetes_filtered %>%
  group_by(Age) %>%
  summarise(
    Mean = mean(DiabetesPedigreeFunction, na.rm = TRUE),
    Median = median(DiabetesPedigreeFunction, na.rm = TRUE),
    SD = sd(DiabetesPedigreeFunction, na.rm = TRUE),
    Min = min(DiabetesPedigreeFunction, na.rm = TRUE),
    Max = max(DiabetesPedigreeFunction, na.rm = TRUE),
    Count = n()
  )

# Mostrar el resumen estadístico
kable(summary_stats, format = "latex", booktabs = TRUE, caption = "Resumen Estadístico de DiabetesPedigreeFunction por Edad (20-39 años)")
Code
#| label: filtrar-edad-70plus


#| fig-width: 5
#| fig-asp: 0.618
#| fig-alt: "Filtrar y manejar valores NA en el conjunto de datos diabetes"
#| fig-cap: "Filtrado del conjunto de datos para incluir solo personas de 70 años o más y manejo de valores NA en la columna BMI."

# Filtrar el grupo de edad 70+ y manejar valores NA
diabetes_70plus <- diabetes %>%
  filter(Age >= 70) %>%
  mutate(BMI = ifelse(is.na(BMI), median(BMI, na.rm = TRUE), BMI)) # Imputar valores NA con la mediana
Code
#| label: recode-insulin-known


#| fig-width: 5
#| fig-asp: 0.618
#| fig-alt: "Recode de la variable InsulinKnown"
#| fig-cap: "Recode de valores en la variable InsulinKnown en el conjunto de datos diabetes_70plus."

diabetes_70plus <- diabetes_70plus %>%
  mutate(InsulinKnown = recode(InsulinKnown, `3` = 0))
Code
#| fig-width: 5
#| fig-asp: 0.618
#| fig-alt: "Resumen estadístico del BMI por grupo de Outcome"
#| fig-cap: "Resumen estadístico del BMI para cada grupo de Outcome en el conjunto de datos diabetes_70plus."



 #Resumen estadístico del BMI
summary_bmi <- diabetes_70plus %>% 
  group_by(Outcome) %>% 
  summarise(mean_bmi = mean(BMI, na.rm = TRUE),
            sd_bmi = sd(BMI, na.rm = TRUE),
            median_bmi = median(BMI, na.rm = TRUE),
            min_bmi = min(BMI, na.rm = TRUE),
            max_bmi = max(BMI, na.rm = TRUE))

print(summary_bmi)
## # A tibble: 2 × 6
##   Outcome mean_bmi sd_bmi median_bmi min_bmi max_bmi
##     <int>    <dbl>  <dbl>      <dbl>   <dbl>   <dbl>
## 1       0     22.8   4.45       22.8    19.6    25.9
## 2       1     32.5  NA          32.5    32.5    32.5