1. Exploren los datos asignados a su grupo
df <- read_csv("Grupo_2.csv")
## Rows: 100 Columns: 12
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (6): Ciudad, Nivel_Educativo, Estado_Civil, Sector_Laboral, Propietario_...
## dbl (6): ID, Edad, Salario, Experiencia, Horas_Trabajo_Semana, Cantidad_Hijos
##
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
head(df)
## # A tibble: 6 × 12
## ID Edad Salario Experiencia Ciudad Nivel_Educativo Horas_Trabajo_Semana
## <dbl> <dbl> <dbl> <dbl> <chr> <chr> <dbl>
## 1 1 35 27203 NA Ponce Primaria 54
## 2 2 43 45647 10 San Juan Primaria 36
## 3 3 53 42181 10 Caguas Universitario 26
## 4 4 38 58530 20 Ponce Universitario 45
## 5 5 58 76972 NA Ponce Universitario 59
## 6 6 46 59877 NA Caguas Primaria 60
## # ℹ 5 more variables: Estado_Civil <chr>, Sector_Laboral <chr>,
## # Cantidad_Hijos <dbl>, Propietario_Vivienda <chr>, Rango_Salario <chr>
dim(df)
## [1] 100 12
glimpse(df)
## Rows: 100
## Columns: 12
## $ ID <dbl> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15…
## $ Edad <dbl> 35, 43, 53, 38, 58, 46, 38, 62, 35, 30, 45, 33, 3…
## $ Salario <dbl> 27203, 45647, 42181, 58530, 76972, 59877, 30183, …
## $ Experiencia <dbl> NA, 10, 10, 20, NA, NA, 26, 29, 38, 24, 30, 30, 2…
## $ Ciudad <chr> "Ponce", "San Juan", "Caguas", "Ponce", "Ponce", …
## $ Nivel_Educativo <chr> "Primaria", "Primaria", "Universitario", "Univers…
## $ Horas_Trabajo_Semana <dbl> 54, 36, 26, 45, 59, 60, 22, 41, 49, 33, 28, 50, 5…
## $ Estado_Civil <chr> "Casado", "Casado", NA, "Casado", "Casado", "Casa…
## $ Sector_Laboral <chr> "Público", "Público", "Independiente", "Público",…
## $ Cantidad_Hijos <dbl> 3, 3, 5, NA, 5, 4, 0, 0, 3, 5, 5, 3, NA, 2, 1, 3,…
## $ Propietario_Vivienda <chr> "No", "No", "Sí", "Sí", "Sí", "No", "Sí", "Sí", "…
## $ Rango_Salario <chr> "Bajo", "Medio", "Medio", "Medio", "Alto", "Medio…
summary(df)
## ID Edad Salario Experiencia
## Min. : 1.00 Min. :18.00 Min. :20213 Min. : 0.00
## 1st Qu.: 25.75 1st Qu.:31.00 1st Qu.:37544 1st Qu.:10.00
## Median : 50.50 Median :46.00 Median :52147 Median :19.00
## Mean : 50.50 Mean :43.65 Mean :50512 Mean :19.96
## 3rd Qu.: 75.25 3rd Qu.:56.00 3rd Qu.:62582 3rd Qu.:30.00
## Max. :100.00 Max. :64.00 Max. :79438 Max. :40.00
## NA's :7 NA's :9 NA's :11
## Ciudad Nivel_Educativo Horas_Trabajo_Semana Estado_Civil
## Length:100 Length:100 Min. :20.00 Length:100
## Class :character Class :character 1st Qu.:28.00 Class :character
## Mode :character Mode :character Median :41.00 Mode :character
## Mean :39.65
## 3rd Qu.:49.00
## Max. :60.00
## NA's :3
## Sector_Laboral Cantidad_Hijos Propietario_Vivienda Rango_Salario
## Length:100 Min. :0.000 Length:100 Length:100
## Class :character 1st Qu.:1.000 Class :character Class :character
## Mode :character Median :3.000 Mode :character Mode :character
## Mean :2.787
## 3rd Qu.:4.000
## Max. :5.000
## NA's :11
2. Identifiquen los problemas en los datos.
Valores faltantes
vis_miss(df)
colSums(is.na(df))
## ID Edad Salario
## 0 7 9
## Experiencia Ciudad Nivel_Educativo
## 11 4 3
## Horas_Trabajo_Semana Estado_Civil Sector_Laboral
## 3 4 1
## Cantidad_Hijos Propietario_Vivienda Rango_Salario
## 11 3 9
Inconsistencias
df %>% filter(!is.na(Edad), !is.na(Experiencia), Experiencia > Edad) %>% select(Edad, Experiencia)
## # A tibble: 10 × 2
## Edad Experiencia
## <dbl> <dbl>
## 1 35 38
## 2 18 37
## 3 26 30
## 4 25 35
## 5 23 28
## 6 25 40
## 7 20 37
## 8 25 27
## 9 20 36
## 10 28 29
Posibles valores extremos
df %>% select(where(is.numeric)) %>% summary()
## ID Edad Salario Experiencia
## Min. : 1.00 Min. :18.00 Min. :20213 Min. : 0.00
## 1st Qu.: 25.75 1st Qu.:31.00 1st Qu.:37544 1st Qu.:10.00
## Median : 50.50 Median :46.00 Median :52147 Median :19.00
## Mean : 50.50 Mean :43.65 Mean :50512 Mean :19.96
## 3rd Qu.: 75.25 3rd Qu.:56.00 3rd Qu.:62582 3rd Qu.:30.00
## Max. :100.00 Max. :64.00 Max. :79438 Max. :40.00
## NA's :7 NA's :9 NA's :11
## Horas_Trabajo_Semana Cantidad_Hijos
## Min. :20.00 Min. :0.000
## 1st Qu.:28.00 1st Qu.:1.000
## Median :41.00 Median :3.000
## Mean :39.65 Mean :2.787
## 3rd Qu.:49.00 3rd Qu.:4.000
## Max. :60.00 Max. :5.000
## NA's :3 NA's :11
3. Propongan estrategias de preprocesamiento para solucionar estos problemas.
1. Para las variables con valores faltantes, decidan cuál método de imputación aplicar (media, mediana, moda, regresión, eliminación, etc.).
Se utilizarán dos estrategias de imputación:
Imputación simple: - Variables numéricas -> Mediana - Variables categóricas -> Moda
Imputación multivariada: - Método MICE (Multiple Imputation by Chained Equations)
Estas estrategias permiten comparar un método simple con uno más avanzado que utiliza información de múltiples variables.
2. Justifiquen su elección con base en la naturaleza de los datos.
Se utilizaron diferentes métodos de imputación dependiendo del tipo de variable. Para las variables numéricas (Edad, Salario, Experiencia, Horas_Trabajo_Semana y Cantidad_Hijos) se utilizó la mediana, ya que ayuda a evitar que valores extremos afecten demasiado los resultados y permite mantener el tamaño de la muestra. Para las variables categóricas (Ciudad, Nivel_Educativo, Estado_Civil, Sector_Laboral y Propietario_Vivienda) se utilizó la moda, porque simplemente reemplaza los valores faltantes con la categoría que aparece con más frecuencia en los datos. Además, se utilizó imputación multivariada con el paquete mice, que estima los valores faltantes utilizando la información de varias variables al mismo tiempo, lo que ayuda a conservar mejor la relación entre los datos.
3. Apliquen diferentes estrategias de imputación según las características de las variables de su conjunto de datos.
Mediana
# Imputación numéricas con mediana
df_median <- df %>%
mutate(across(where(is.numeric),
~ ifelse(is.na(.x), median(.x, na.rm = TRUE), .x)))
data_median_long <- bind_rows(
df %>% select(where(is.numeric)) %>% mutate(Origen = "Original"),
df_median %>% select(where(is.numeric)) %>% mutate(Origen = "Imputado (Mediana)")
) %>%
pivot_longer(cols = -Origen, names_to = "Variable", values_to = "Valor") %>%
filter(!is.na(Valor))
p_median <- ggplot(data_median_long, aes(x = Valor, color = Origen, fill = Origen, text = Origen)) +
geom_density(alpha = 0.2) +
facet_wrap(~Variable, scales = "free") +
labs(title = "Original vs Imputado con Mediana (Variables numéricas)", x = "Valor", y = "Densidad") +
theme_minimal()
ggplotly(p_median, tooltip = c("text", "x", "y"))
Moda
cat_vars <- c("Ciudad","Nivel_Educativo","Estado_Civil" ,"Sector_Laboral","Propietario_Vivienda","Rango_Salario")
df <- as.data.frame(df)
# Asegura que sean categóricas
df_cat <- df %>% mutate(across(all_of(cat_vars), as.factor))
# Imputa SOLO las categóricas con CART
meth <- make.method(df_cat)
meth[] <- ""
meth[cat_vars] <- "cart"
Imput_mode <- mice(df_cat, method = meth, m = 5, maxit = 5, printFlag = FALSE, seed = 123)
Complete_mode <- mice::complete(Imput_mode, 1)
# Comparación Original vs Imputado (todas las categóricas)
data_cat <- bind_rows(
df_cat %>% select(all_of(cat_vars)) %>% mutate(Origen = "Original"),
Complete_mode %>% select(all_of(cat_vars)) %>% mutate(Origen = "Imputado")
) %>%
pivot_longer(cols = all_of(cat_vars), names_to = "Variable", values_to = "Valor") %>%
filter(!is.na(Valor)) %>%
count(Variable, Origen, Valor, name = "Frecuencia")
# Gráfico de barras por variable (facetas)
p2 <- ggplot(
data_cat,
aes(
x = Valor, y = Frecuencia, fill = Origen,
text = paste0("Variable: ", Variable,
"<br>Origen: ", Origen,
"<br>Valor: ", Valor,
"<br>Frecuencia: ", Frecuencia)
)
) +
geom_col(position = "dodge") +
facet_wrap(~Variable, scales = "free_x") +
labs(title = "Categóricas: Original vs Imputado (CART)", x = "Categoría", y = "Frecuencia") +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
p2
Mice
num_vars <- c("Edad","Salario","Experiencia","Horas_Trabajo_Semana","Cantidad_Hijos")
df_num <- df %>% select(all_of(num_vars)) %>% as.data.frame()
meth <- make.method(df_num); meth[] <- "pmm"
Imput_pmm <- mice(df_num, method = meth, m = 1, maxit = 2, printFlag = FALSE, seed = 123)
Complete_pmm <- mice::complete(Imput_pmm, 1)
data_long <- bind_rows(
df_num %>% mutate(Origen = "Original"),
Complete_pmm %>% mutate(Origen = "Imputado (PMM)")
) %>%
pivot_longer(cols = all_of(num_vars), names_to = "Variable", values_to = "Valor") %>%
filter(!is.na(Valor))
p <- ggplot(data_long, aes(x = Valor, color = Origen, fill = Origen)) +
geom_density(alpha = 0.2, na.rm = TRUE) +
facet_wrap(~Variable, scales = "free") +
labs(title = "Original vs Imputado (PMM)", x = "Valor", y = "Densidad") +
theme_minimal()
p
4. Comparen los resultados obtenidos con cada estrategia y expliquen cuál es la más adecuada en su caso.
Mediana:
Sugiere que la mediana no cambió de forma importante la distribución general.Imputación.
Moda
Se mantiene igual el imputado y el original.
MICE (pmm):
Sugiere que MICE preserva bien la distribución y, al ser multivariado, tiende a conservar mejor las relaciones entre variables que un método univariado.
Conclusión:
Para este conjunto de datos, la imputación multivariada con MICE (pmm) es la más adecuada para las variables numéricas porque mantiene la distribución observada y ayuda a preservar relaciones entre variables.
5. Expliquen cómo la elección del método de imputación afecta el análisis posterior de los datos.
El método de imputación puede modificar tanto la distribución de las variables como las relaciones entre ellas.
Media/mediana pueden reducir la variabilidad, especialmente si hay muchos faltantes, lo que puede afectar histogramas/densidades y también impactar medidas como la desviación estándar.
Moda puede aumentar la frecuencia de una categoría específica, alterando proporciones y comparaciones entre grupos..
MICE (pmm) suele preservar mejor la distribución y las relaciones multivariadas, por lo que puede producir conclusiones más consistentes cuando el análisis depende de correlaciones, modelos predictivos o comparaciones entre variables.