En este trabajo, estaremos revisando y procesando una base de datos incompleta o con errores, para preparar los datos antes de entrar a un análisis más profundo de lo que se quiere estudiar con esta base de datos.
Para poder explorar los datos descargamos la base de datos llamada “datos” y descargamos la librería de “dplyr”, “tidyr” y “readr”.
## Warning: package 'readr' was built under R version 4.5.2
## 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.
Utilizamos estos codigos para que nos ayuden a visualizar los problemas en los datos. Cuantos datos faltantes hay en cada variable y cuanto representa en porcentaje a la base de datos para ver que variables debemos considerar para imputaciones o no.
| Name | datos |
| Number of rows | 100 |
| Number of columns | 12 |
| _______________________ | |
| Column type frequency: | |
| character | 6 |
| numeric | 6 |
| ________________________ | |
| Group variables | None |
Variable type: character
| skim_variable | n_missing | complete_rate | min | max | empty | n_unique | whitespace |
|---|---|---|---|---|---|---|---|
| Ciudad | 1 | 0.99 | 5 | 8 | 0 | 4 | 0 |
| Nivel_Educativo | 2 | 0.98 | 8 | 13 | 0 | 3 | 0 |
| Estado_Civil | 3 | 0.97 | 6 | 10 | 0 | 3 | 0 |
| Sector_Laboral | 3 | 0.97 | 7 | 13 | 0 | 3 | 0 |
| Propietario_Vivienda | 4 | 0.96 | 2 | 2 | 0 | 2 | 0 |
| Rango_Salario | 6 | 0.94 | 4 | 5 | 0 | 3 | 0 |
Variable type: numeric
| skim_variable | n_missing | complete_rate | mean | sd | p0 | p25 | p50 | p75 | p100 | hist |
|---|---|---|---|---|---|---|---|---|---|---|
| ID | 0 | 1.00 | 50.50 | 29.01 | 1 | 25.75 | 50.5 | 75.25 | 100 | ▇▇▇▇▇ |
| Edad | 5 | 0.95 | 42.37 | 12.80 | 18 | 31.50 | 45.0 | 52.00 | 65 | ▅▅▇▅▆ |
| Salario | 6 | 0.94 | 47376.93 | 16970.77 | 20029 | 33211.00 | 47024.0 | 61996.50 | 79746 | ▇▆▇▆▅ |
| Experiencia | 9 | 0.91 | 20.96 | 11.94 | 0 | 10.50 | 22.0 | 31.00 | 40 | ▇▆▇▇▇ |
| Horas_Trabajo_Semana | 4 | 0.96 | 40.35 | 11.74 | 20 | 31.00 | 41.5 | 50.00 | 60 | ▆▇▆▇▆ |
| Cantidad_Hijos | 7 | 0.93 | 2.43 | 1.80 | 0 | 1.00 | 2.0 | 4.00 | 5 | ▇▃▁▃▃ |
Según la visualización de valores faltantes, el conjunto de datos presenta un porcentaje bajo de missing (4.2). No se recomendamos eliminar observaciones, ya que se perdería información útil sin necesidad. En este caso estaremos imputando los valores faltantes. Así que, para variables numéricas como Edad, Salario, Experiencia y Horas_Trabajo_Semana se considerará método simple (media) y métodos basados en modelos (regresión) para comparar resultados.
Para poder solucionar estos problemas de datos faltantes decidimos utilizar utilizaremos:
“Imputación por media” para variables numericas como salario, experiencia, cantidad de hijos, ya que tienen un porcentaje faltante mayor a 5%. (Las demás faltantes podemos ignorarlas)
“Imputación por moda” para las Variables Categorícas como ciudad, nivel de educación, Estado_civil, propetario de vivienda, rango salarial y sector laboral.
Estudiar el comportamiento de las imputaciones vs la distribución original y metodo cart.
Convertir las variables categóricas a factores para facilitar su análisis.
## Warning: Number of logged events: 6
## Warning: Number of logged events: 6
Elegimos imputaciones por media y moda, para enfocarnos en imputaciones univariadas basandonos en una sola variable a la vez. Media es para reemplazar los valores faltantes de variables numericas y moda es para reemplazar los valores faltantes de variables categóricas.
datos_long <- bind_rows(
datos %>% select(Edad, Salario, Experiencia, Horas_Trabajo_Semana, Cantidad_Hijos) %>% mutate(Origen = "Original"),
datos.imput %>% select(Edad, Salario, Experiencia, Horas_Trabajo_Semana, Cantidad_Hijos) %>% mutate(Origen = "Imputación con la Media"),
datos.imput.mode %>% select(Edad, Salario, Experiencia, Horas_Trabajo_Semana, Cantidad_Hijos) %>% mutate(Origen = "Imputación con Moda")) %>%
pivot_longer(cols = c(Edad, Salario, Experiencia, Horas_Trabajo_Semana, Cantidad_Hijos), names_to = "Variable", values_to = "Valor")
datos_longp <- ggplot(datos_long, aes(x = Valor, color = Origen, fill = Origen, text = paste("Origen:", Origen))) +
geom_density(alpha = 0.2) +
facet_wrap(~Variable, scales = "free") +
labs(title = "Comportamiento de la Imputación", x = "Variables", y = "Densidad") +
theme_minimal()
# Convertir a gráfico interactivo sin duplicaciones en el tooltip
ggplotly(p, tooltip = c("text", "x", "y"))## Warning: Removed 31 rows containing non-finite outside the scale range
## (`stat_density()`).
Observación:
Al ver estas gráficas comparamos la distribución de los datos Originales, los datos imputados por media y por moda. La media muestra una ligera concentración alrededor del valor promedio, especialmente en variables como Edad y Experiencia, lo cual puede reducir la variabilidad.La imputación con moda se mantiene más cercana a la distribución original en algunas variables, aunque las diferencias entre métodos es poca, lo que nos puede indicar que la imputación no altera significativamente la estructura general de los datos.
Cuando vemos la gráfica podemos ver que la imputación por media para las variables numericas tiende a reducir la variabilidad de los datos al reemplazar los valores faltantes con un valor central. Por otro lado, el método por la moda puede preservar mejor la estructura original de los datos para las variables categóricas. Así que seleccionamos el metodo el método de imputación por Media para variables numericas y la moda para variables categorícas.
En este caso estaremos utilizando “age.categories()”:
datos <- datos.imput %>%
mutate(across(.cols = c(Nivel_Educativo, Estado_Civil, Sector_Laboral, Propietario_Vivienda, Rango_Salario), .fns = as.character))
datosSe transformaron variables como Nivel_Educativo, Estado_Civil, Sector_Laboral, Propietario_Vivienda y Rango_Salarial a tipo carácter porque representan categorías y no valores numéricos. Al convertirlas a un formato categórico, evita que R las interprete como números y se asegura que puedan ser utilizadas correctamente en análisis, visualizaciones.
corr <- cor(dplyr::select_if(datos, is.numeric))
plot_ly(color = "RdBu") %>%
add_heatmap(x = rownames(corr), y = colnames(corr), z = corr) %>%
colorbar(limits = c(-1, 1))## Warning: Didn't find a colorbar to modify.
## ID Edad Salario Experiencia
## ID 1.0000000000 -0.05789336 -0.0005180034 -0.14962735
## Edad -0.0578933634 1.00000000 -0.0216694123 0.02657322
## Salario -0.0005180034 -0.02166941 1.0000000000 -0.06092148
## Experiencia -0.1496273491 0.02657322 -0.0609214819 1.00000000
## Horas_Trabajo_Semana -0.0589011674 0.14802605 -0.1029745249 0.04090987
## Cantidad_Hijos -0.1109501759 -0.01500272 -0.0365496171 -0.04391182
## Horas_Trabajo_Semana Cantidad_Hijos
## ID -0.058901167 -0.110950176
## Edad 0.148026047 -0.015002715
## Salario -0.102974525 -0.036549617
## Experiencia 0.040909874 -0.043911824
## Horas_Trabajo_Semana 1.000000000 -0.003471772
## Cantidad_Hijos -0.003471772 1.000000000
Observaciones:
Se puede observar que la mayoría de las correlaciones entre las variables numéricas son débiles o cercanas a cero, lo que indica que no existen relaciones lineales fuertes entre ellas. Se observa una correlación positiva moderada entre Edad y Experiencia, lo cual tiene sentido ya que a mayor edad generalmente se acumulan más años de experiencia laboral. Además, Horas_Trabajo_Semana presenta una ligera relación con algunas variables, pero en general el dataset muestra baja multicolinealidad, lo que sugiere que las variables aportan información relativamente independiente.
barras <- ggplot(datos,
aes(x = Rango_Salario,
y = Cantidad_Hijos)) +
geom_bar(stat = "summary",
fun = "mean",
fill = "darkgreen") +
theme_minimal()
ggplotly(barras)Observaciones:
Se observa que las personas en el rango salarial bajo tienen en promedio una mayor cantidad de hijos, mientras que en los rangos medio y alto el promedio es ligeramente menor. Sin embargo, las diferencias entre los grupos no son muy grandes, lo que sugiere que el rango de salario no presenta una relación fuerte con la cantidad de hijos en este conjunto de datos.
dispersion <- ggplot(datos,
aes(x = Experiencia,
y = Salario)) +
geom_point(color = "darkblue", alpha = 0.6) +
theme_minimal()
ggplotly(dispersion)Observación:
Al ver el gráfico, no se observa una relación lineal fuerte entre ambas variables, ya que los puntos están bastante dispersos a lo largo del gráfico. Aunque algunos niveles altos de salario muestra alto nivel de experiencia, bajo salarios a un alto nivel de experiencia. Esto sugiere que, en este conjunto de datos, la experiencia por sí sola no explica completamente las diferencias en el salario.