2024-06-06

Librerías a usar

install.packages("Amelia")
## Installing package into '/cloud/lib/x86_64-pc-linux-gnu-library/4.3'
## (as 'lib' is unspecified)
install.packages("janitor")
## Installing package into '/cloud/lib/x86_64-pc-linux-gnu-library/4.3'
## (as 'lib' is unspecified)
install.packages("pastecs")
## Installing package into '/cloud/lib/x86_64-pc-linux-gnu-library/4.3'
## (as 'lib' is unspecified)
library(readxl)
library(dplyr)
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ forcats   1.0.0     ✔ readr     2.1.4
## ✔ ggplot2   3.4.2     ✔ stringr   1.5.0
## ✔ lubridate 1.9.2     ✔ tibble    3.2.1
## ✔ purrr     1.0.2     ✔ tidyr     1.3.0
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(ggplot2)
library(Amelia)
## Loading required package: Rcpp
## ## 
## ## Amelia II: Multiple Imputation
## ## (Version 1.8.2, built: 2024-04-10)
## ## Copyright (C) 2005-2024 James Honaker, Gary King and Matthew Blackwell
## ## Refer to http://gking.harvard.edu/amelia/ for more information
## ##
library(janitor)
## 
## Attaching package: 'janitor'
## 
## The following objects are masked from 'package:stats':
## 
##     chisq.test, fisher.test
library(magrittr)
## 
## Attaching package: 'magrittr'
## 
## The following object is masked from 'package:purrr':
## 
##     set_names
## 
## The following object is masked from 'package:tidyr':
## 
##     extract
library(pastecs)
## 
## Attaching package: 'pastecs'
## 
## The following object is masked from 'package:magrittr':
## 
##     extract
## 
## The following object is masked from 'package:tidyr':
## 
##     extract
## 
## The following objects are masked from 'package:dplyr':
## 
##     first, last

Creación de la base de datos

datos <- read_excel("Datos_Final.xlsx")
view(datos)
summary(datos)
##        ID             Edad          Género          Nivel Educativo   
##  Min.   :  1.0   Min.   :18.00   Length:845         Length:845        
##  1st Qu.:206.0   1st Qu.:31.00   Class :character   Class :character  
##  Median :422.0   Median :45.00   Mode  :character   Mode  :character  
##  Mean   :422.2   Mean   :43.97                                        
##  3rd Qu.:635.0   3rd Qu.:56.00                                        
##  Max.   :845.0   Max.   :69.00                                        
##  NA's   :84      NA's   :84                                           
##  Estado Civil        Ocupación            Ingresos        Estrés      
##  Length:845         Length:845         Min.   : 506   Min.   : 1.000  
##  Class :character   Class :character   1st Qu.:1804   1st Qu.: 3.000  
##  Mode  :character   Mode  :character   Median :2968   Median : 6.000  
##                                        Mean   :2862   Mean   : 5.573  
##                                        3rd Qu.:3974   3rd Qu.: 8.000  
##                                        Max.   :4998   Max.   :10.000  
##                                        NA's   :84     NA's   :84      
##     Ansiedad        Depresión      Satisfacción con la vida Soporte Social  
##  Min.   : 1.000   Min.   : 1.000   Min.   : 1.00            Min.   : 1.000  
##  1st Qu.: 3.000   1st Qu.: 3.000   1st Qu.: 3.00            1st Qu.: 3.000  
##  Median : 6.000   Median : 6.000   Median : 5.00            Median : 6.000  
##  Mean   : 5.551   Mean   : 5.594   Mean   : 5.49            Mean   : 5.548  
##  3rd Qu.: 8.000   3rd Qu.: 8.000   3rd Qu.: 8.00            3rd Qu.: 8.000  
##  Max.   :10.000   Max.   :10.000   Max.   :10.00            Max.   :10.000  
##  NA's   :84       NA's   :84       NA's   :84               NA's   :84      
##      Sueño        Actividad Física Consumo de Agua    Felicidad     
##  Min.   : 1.000   Min.   : 1.000   Min.   : 1.000   Min.   : 1.000  
##  1st Qu.: 3.000   1st Qu.: 3.000   1st Qu.: 3.000   1st Qu.: 3.000  
##  Median : 5.000   Median : 5.000   Median : 6.000   Median : 6.000  
##  Mean   : 5.523   Mean   : 5.434   Mean   : 5.653   Mean   : 5.548  
##  3rd Qu.: 8.000   3rd Qu.: 8.000   3rd Qu.: 8.000   3rd Qu.: 8.000  
##  Max.   :10.000   Max.   :10.000   Max.   :10.000   Max.   :10.000  
##  NA's   :84       NA's   :84       NA's   :84       NA's   :84      
##     Estatura    
##  Min.   :150.0  
##  1st Qu.:162.0  
##  Median :176.0  
##  Mean   :174.9  
##  3rd Qu.:187.0  
##  Max.   :199.0  
##  NA's   :84
dim(datos)
## [1] 845  17
str(datos)
## tibble [845 × 17] (S3: tbl_df/tbl/data.frame)
##  $ ID                      : num [1:845] 1 2 3 4 NA 6 7 8 9 10 ...
##  $ Edad                    : num [1:845] 56 69 46 32 60 25 38 56 36 40 ...
##  $ Género                  : chr [1:845] "Masculino" "Otro" "Masculino" "Masculino" ...
##  $ Nivel Educativo         : chr [1:845] "Primaria" "Universitario" "Posgrado" "Secundaria" ...
##  $ Estado Civil            : chr [1:845] "Casado" "Soltero" "Viudo" "Soltero" ...
##  $ Ocupación               : chr [1:845] "Empleado" "Desempleado" "Desempleado" "Estudiante" ...
##  $ Ingresos                : num [1:845] 2366 2496 1409 4805 3689 ...
##  $ Estrés                  : num [1:845] 4 9 10 3 8 1 9 9 10 2 ...
##  $ Ansiedad                : num [1:845] 4 9 NA 7 6 NA 5 1 1 9 ...
##  $ Depresión               : num [1:845] 3 2 NA 4 8 3 1 NA NA 1 ...
##  $ Satisfacción con la vida: num [1:845] NA 4 8 5 NA 9 10 NA 1 9 ...
##  $ Soporte Social          : num [1:845] 7 6 6 NA 3 3 10 9 8 5 ...
##  $ Sueño                   : num [1:845] NA NA 2 3 6 7 4 1 NA 9 ...
##  $ Actividad Física        : num [1:845] 5 8 5 NA 8 2 3 9 5 5 ...
##  $ Consumo de Agua         : num [1:845] 4 8 NA 7 10 NA 10 5 7 4 ...
##  $ Felicidad               : num [1:845] 1 5 8 7 5 3 1 7 3 4 ...
##  $ Estatura                : num [1:845] 196 172 NA 184 174 181 171 157 187 167 ...
#Eliminamos la columna ID del dataframe original
datos_sin_ID <- select(datos, -ID)

#Creamos una nueva secuencia numérica del mismo tamaño que el dataframe original
nuevos_ID <- 1:nrow(datos)

#Agregamos la nueva columna al dataframe sin datos
nuevos_datos <- bind_cols(ID = nuevos_ID, datos_sin_ID)

print(head(nuevos_datos))
## # A tibble: 6 × 17
##      ID  Edad Género  `Nivel Educativo` `Estado Civil` Ocupación Ingresos Estrés
##   <int> <dbl> <chr>   <chr>             <chr>          <chr>        <dbl>  <dbl>
## 1     1    56 Mascul… Primaria          Casado         Empleado      2366      4
## 2     2    69 Otro    Universitario     Soltero        Desemple…     2496      9
## 3     3    46 Mascul… Posgrado          Viudo          Desemple…     1409     10
## 4     4    32 Mascul… Secundaria        Soltero        Estudian…     4805      3
## 5     5    60 Femeni… Universitario     Casado         Empleado      3689      8
## 6     6    25 <NA>    Posgrado          Viudo          Autónomo      1270      1
## # ℹ 9 more variables: Ansiedad <dbl>, Depresión <dbl>,
## #   `Satisfacción con la vida` <dbl>, `Soporte Social` <dbl>, Sueño <dbl>,
## #   `Actividad Física` <dbl>, `Consumo de Agua` <dbl>, Felicidad <dbl>,
## #   Estatura <dbl>
nuevos_datos$ID <- as.character(nuevos_datos$ID)
str(datos)
## tibble [845 × 17] (S3: tbl_df/tbl/data.frame)
##  $ ID                      : num [1:845] 1 2 3 4 NA 6 7 8 9 10 ...
##  $ Edad                    : num [1:845] 56 69 46 32 60 25 38 56 36 40 ...
##  $ Género                  : chr [1:845] "Masculino" "Otro" "Masculino" "Masculino" ...
##  $ Nivel Educativo         : chr [1:845] "Primaria" "Universitario" "Posgrado" "Secundaria" ...
##  $ Estado Civil            : chr [1:845] "Casado" "Soltero" "Viudo" "Soltero" ...
##  $ Ocupación               : chr [1:845] "Empleado" "Desempleado" "Desempleado" "Estudiante" ...
##  $ Ingresos                : num [1:845] 2366 2496 1409 4805 3689 ...
##  $ Estrés                  : num [1:845] 4 9 10 3 8 1 9 9 10 2 ...
##  $ Ansiedad                : num [1:845] 4 9 NA 7 6 NA 5 1 1 9 ...
##  $ Depresión               : num [1:845] 3 2 NA 4 8 3 1 NA NA 1 ...
##  $ Satisfacción con la vida: num [1:845] NA 4 8 5 NA 9 10 NA 1 9 ...
##  $ Soporte Social          : num [1:845] 7 6 6 NA 3 3 10 9 8 5 ...
##  $ Sueño                   : num [1:845] NA NA 2 3 6 7 4 1 NA 9 ...
##  $ Actividad Física        : num [1:845] 5 8 5 NA 8 2 3 9 5 5 ...
##  $ Consumo de Agua         : num [1:845] 4 8 NA 7 10 NA 10 5 7 4 ...
##  $ Felicidad               : num [1:845] 1 5 8 7 5 3 1 7 3 4 ...
##  $ Estatura                : num [1:845] 196 172 NA 184 174 181 171 157 187 167 ...
names(datos)
##  [1] "ID"                       "Edad"                    
##  [3] "Género"                   "Nivel Educativo"         
##  [5] "Estado Civil"             "Ocupación"               
##  [7] "Ingresos"                 "Estrés"                  
##  [9] "Ansiedad"                 "Depresión"               
## [11] "Satisfacción con la vida" "Soporte Social"          
## [13] "Sueño"                    "Actividad Física"        
## [15] "Consumo de Agua"          "Felicidad"               
## [17] "Estatura"
datos %<>% clean_names()
names(datos)
##  [1] "id"                       "edad"                    
##  [3] "genero"                   "nivel_educativo"         
##  [5] "estado_civil"             "ocupacion"               
##  [7] "ingresos"                 "estres"                  
##  [9] "ansiedad"                 "depresion"               
## [11] "satisfaccion_con_la_vida" "soporte_social"          
## [13] "sueno"                    "actividad_fisica"        
## [15] "consumo_de_agua"          "felicidad"               
## [17] "estatura"
unique(datos$genero)
## [1] "Masculino" "Otro"      "Femenino"  NA
unique(datos$nivel_educativo)
## [1] "Primaria"      "Universitario" "Posgrado"      "Secundaria"   
## [5] NA
unique(datos$estado_civil)
## [1] "Casado"     "Soltero"    "Viudo"      "Divorciado" NA
unique(datos$ocupacion)
## [1] "Empleado"    "Desempleado" "Estudiante"  "Autónomo"    NA

Tratamiento de los NA

Gráfico de los datos faltantes

missmap(nuevos_datos, main = "Mapa de datos Faltantes")
## Warning: Unknown or uninitialised column: `arguments`.
## Unknown or uninitialised column: `arguments`.
## Warning: Unknown or uninitialised column: `imputations`.

Pruebas de Normalidad

normality_tests <- nuevos_datos %>%
  summarise(across(where(is.numeric), ~ shapiro.test(.x)$p.value)) %>%
  pivot_longer(cols = everything(), names_to = "Variable", values_to = "P-Value")

#Agregar una Columna indicando si los dato son normales o no
normality_tests <- normality_tests %>%
  mutate(Normal = ifelse(`P-Value` < 0.05, "No", "Sí"))

#Mostrar los resultados
print(normality_tests)
## # A tibble: 12 × 3
##    Variable                 `P-Value` Normal
##    <chr>                        <dbl> <chr> 
##  1 Edad                      4.59e-14 No    
##  2 Ingresos                  1.49e-14 No    
##  3 Estrés                    8.67e-18 No    
##  4 Ansiedad                  1.37e-16 No    
##  5 Depresión                 7.24e-19 No    
##  6 Satisfacción con la vida  9.98e-18 No    
##  7 Soporte Social            8.35e-18 No    
##  8 Sueño                     4.78e-18 No    
##  9 Actividad Física          2.80e-17 No    
## 10 Consumo de Agua           9.84e-19 No    
## 11 Felicidad                 1.49e-17 No    
## 12 Estatura                  1.07e-15 No

Funciones para tratar los NA en las variables

# Función para rellenar variables cuantitativas con la mediana
rellenar_con_mediana <- function(x) {
  x[is.na(x)] <- median(x, na.rm = TRUE)
  return(x)
}

# Función para calcular la moda
calcular_moda <- function(x) {
  uniq_vals <- unique(na.omit(x))
  uniq_vals[which.max(tabulate(match(x, uniq_vals)))]
}

# Función para rellenar NA en variables cualitativas con la moda
rellenar_con_moda <- function(x) {
  moda <- calcular_moda(x)
  x[is.na(x)] <- moda
  return(x)
}

Reemplazo de los NA

nuevos_datos <- nuevos_datos %>%
  mutate(across(where(is.numeric), rellenar_con_mediana)) %>%
  mutate(across(where(is.character), rellenar_con_moda)) %>%
  mutate(across(where(is.factor), ~ as.character(.) %>% rellenar_con_moda() %>% as.factor()))

# Verificar que no haya NA en el nuevo dataframe
missmap(nuevos_datos, main="Mapa de Datos Faltantes")
## Warning: Unknown or uninitialised column: `arguments`.
## Unknown or uninitialised column: `arguments`.
## Warning: Unknown or uninitialised column: `imputations`.

sum(is.na(nuevos_datos))
## [1] 0

Cómo podemos apreciar, ya no hay datos faltantes en ninguna de las observaciones ni en las variables registradas; por ende, es posible afirmar que los datos están limpios y han recibido un tratamiento acorde a su naturaleza.

Visualización de datos limpios

names(nuevos_datos)
##  [1] "ID"                       "Edad"                    
##  [3] "Género"                   "Nivel Educativo"         
##  [5] "Estado Civil"             "Ocupación"               
##  [7] "Ingresos"                 "Estrés"                  
##  [9] "Ansiedad"                 "Depresión"               
## [11] "Satisfacción con la vida" "Soporte Social"          
## [13] "Sueño"                    "Actividad Física"        
## [15] "Consumo de Agua"          "Felicidad"               
## [17] "Estatura"
nuevos_datos %<>% clean_names()
names(nuevos_datos)
##  [1] "id"                       "edad"                    
##  [3] "genero"                   "nivel_educativo"         
##  [5] "estado_civil"             "ocupacion"               
##  [7] "ingresos"                 "estres"                  
##  [9] "ansiedad"                 "depresion"               
## [11] "satisfaccion_con_la_vida" "soporte_social"          
## [13] "sueno"                    "actividad_fisica"        
## [15] "consumo_de_agua"          "felicidad"               
## [17] "estatura"
summary(nuevos_datos)
##       id                 edad          genero          nivel_educativo   
##  Length:845         Min.   :18.00   Length:845         Length:845        
##  Class :character   1st Qu.:33.00   Class :character   Class :character  
##  Mode  :character   Median :45.00   Mode  :character   Mode  :character  
##                     Mean   :44.08                                        
##                     3rd Qu.:55.00                                        
##                     Max.   :69.00                                        
##  estado_civil        ocupacion            ingresos        estres      
##  Length:845         Length:845         Min.   : 506   Min.   : 1.000  
##  Class :character   Class :character   1st Qu.:1939   1st Qu.: 3.000  
##  Mode  :character   Mode  :character   Median :2968   Median : 6.000  
##                                        Mean   :2873   Mean   : 5.615  
##                                        3rd Qu.:3861   3rd Qu.: 8.000  
##                                        Max.   :4998   Max.   :10.000  
##     ansiedad        depresion      satisfaccion_con_la_vida soporte_social  
##  Min.   : 1.000   Min.   : 1.000   Min.   : 1.000           Min.   : 1.000  
##  1st Qu.: 3.000   1st Qu.: 3.000   1st Qu.: 3.000           1st Qu.: 3.000  
##  Median : 6.000   Median : 6.000   Median : 5.000           Median : 6.000  
##  Mean   : 5.595   Mean   : 5.634   Mean   : 5.441           Mean   : 5.593  
##  3rd Qu.: 8.000   3rd Qu.: 8.000   3rd Qu.: 8.000           3rd Qu.: 8.000  
##  Max.   :10.000   Max.   :10.000   Max.   :10.000           Max.   :10.000  
##      sueno        actividad_fisica consumo_de_agua    felicidad     
##  Min.   : 1.000   Min.   : 1.000   Min.   : 1.000   Min.   : 1.000  
##  1st Qu.: 3.000   1st Qu.: 3.000   1st Qu.: 3.000   1st Qu.: 3.000  
##  Median : 5.000   Median : 5.000   Median : 6.000   Median : 6.000  
##  Mean   : 5.471   Mean   : 5.391   Mean   : 5.688   Mean   : 5.593  
##  3rd Qu.: 8.000   3rd Qu.: 8.000   3rd Qu.: 8.000   3rd Qu.: 8.000  
##  Max.   :10.000   Max.   :10.000   Max.   :10.000   Max.   :10.000  
##     estatura  
##  Min.   :150  
##  1st Qu.:163  
##  Median :176  
##  Mean   :175  
##  3rd Qu.:186  
##  Max.   :199
dim(nuevos_datos)
## [1] 845  17
str(nuevos_datos)
## tibble [845 × 17] (S3: tbl_df/tbl/data.frame)
##  $ id                      : chr [1:845] "1" "2" "3" "4" ...
##  $ edad                    : num [1:845] 56 69 46 32 60 25 38 56 36 40 ...
##  $ genero                  : chr [1:845] "Masculino" "Otro" "Masculino" "Masculino" ...
##  $ nivel_educativo         : chr [1:845] "Primaria" "Universitario" "Posgrado" "Secundaria" ...
##  $ estado_civil            : chr [1:845] "Casado" "Soltero" "Viudo" "Soltero" ...
##  $ ocupacion               : chr [1:845] "Empleado" "Desempleado" "Desempleado" "Estudiante" ...
##  $ ingresos                : num [1:845] 2366 2496 1409 4805 3689 ...
##  $ estres                  : num [1:845] 4 9 10 3 8 1 9 9 10 2 ...
##  $ ansiedad                : num [1:845] 4 9 6 7 6 6 5 1 1 9 ...
##  $ depresion               : num [1:845] 3 2 6 4 8 3 1 6 6 1 ...
##  $ satisfaccion_con_la_vida: num [1:845] 5 4 8 5 5 9 10 5 1 9 ...
##  $ soporte_social          : num [1:845] 7 6 6 6 3 3 10 9 8 5 ...
##  $ sueno                   : num [1:845] 5 5 2 3 6 7 4 1 5 9 ...
##  $ actividad_fisica        : num [1:845] 5 8 5 5 8 2 3 9 5 5 ...
##  $ consumo_de_agua         : num [1:845] 4 8 6 7 10 6 10 5 7 4 ...
##  $ felicidad               : num [1:845] 1 5 8 7 5 3 1 7 3 4 ...
##  $ estatura                : num [1:845] 196 172 176 184 174 181 171 157 187 167 ...
unique(nuevos_datos$genero)
## [1] "Masculino" "Otro"      "Femenino"
unique(nuevos_datos$nivel_educativo)
## [1] "Primaria"      "Universitario" "Posgrado"      "Secundaria"
unique(nuevos_datos$estado_civil)
## [1] "Casado"     "Soltero"    "Viudo"      "Divorciado"
unique(nuevos_datos$ocupacion)
## [1] "Empleado"    "Desempleado" "Estudiante"  "Autónomo"

En ninguna de las variables de tipo “String” se presentan NA, por lo que podemos empezar a trabajar con el dataframe presentado.

Prueba de hipótesis Chi-Cuadrado para la independencia de dos variables categóricas

Objetivo

Determinar si las variables categóricas género y nivel educativo son independientes o no. Para ello, utilizaremos el siguiente planteamiento de hipótesis:

Hipótesis Nula (H0): No hay una asociación entre el género y el nivel educativo

Hipótesis Alternativa (H1): Existe una asociación entre estas dos variables categóricas (género y nivel educativo)

#Creamos una tabla de contingencia con las variables a estudiar
tabla_de_contingencia = table(nuevos_datos$genero , nuevos_datos$nivel_educativo)
#Aplicamos la prueba Chi-Cuadrado la cuál arrojará distintos valores que nos ayudarán a tomar una decisión más adelante.
resultado <- chisq.test(tabla_de_contingencia)
#Planteamiento de las Hipótesis
#Hipótesis Nula (H0): No hay una asociación entre el género y el nivel educativo
#Hipótesis Alternativa (H1): Existe una asociación entre estas dos variables categóricas (género y nivel educativo)
print(resultado)
## 
##  Pearson's Chi-squared test
## 
## data:  tabla_de_contingencia
## X-squared = 2.7887, df = 6, p-value = 0.8349
if (resultado$p.value < 0.05) {
   print("Se rechaza la hipótesis nula, por lo que se afirma que existe una asociación entre estas dos variables")
} else {
  print("No se rechaza la hipótesis nula. Por lo tanto, no es posible concluir que existe una asociación entre el género y el nivel educativo.")
}
## [1] "No se rechaza la hipótesis nula. Por lo tanto, no es posible concluir que existe una asociación entre el género y el nivel educativo."

Decisión

La regla de decisión para este tipo de tests compara el p-valor emitido por la prueba con un nivel de signifcancia, que en este caso es del 5%. Entonces, la decisión final está dada por las siguiente condición:

Si p-valor < nivel de significancia, entonces se rechaza H0

Si p-valor >= nivel de significancia, entonces no se rechaza H0

Cómo podemos apreciar, el p-valor arrojado por la prueba Chi-Cuadrado es de 0.8349, es decir, es mayor que el nivel de significancia considerado (0.05). Por lo que no re rechaza la hipótesis nula y se concluye que no existe una asociación entre el género y el nivel educativo.

Prueba Chicuadrado para la homogeneidad de las variables

#Creamos la tabla de contingencia
tabla_contingencia <- table(nuevos_datos$estado_civil , nuevos_datos$ocupacion)
#Aplicamos la prueba
resultado_prueba <- chisq.test(tabla_contingencia)
print(resultado_prueba)
## 
##  Pearson's Chi-squared test
## 
## data:  tabla_contingencia
## X-squared = 5.4107, df = 9, p-value = 0.7971
#Planteamiento de las hipótesis
#Ho: La distribución de la ocupación es la misma para los diferentes estados civiles
#H1: La distribución de la ocupación difiere entre los distintos estados civiles

#Conclusiones
if (resultado_prueba$p.value < 0.05) {
   print("Se rechaza la hipótesis nula. Por lo que se afirma que la distribución de la ocupción no es homogénea entre los diferentes estados civiles")
} else {
  print("No se rechaza la hipótesis nula. Por lo que no es posible concluir que la distribución de ocupación sea homogénea entre los diferentes estados civiles")
}
## [1] "No se rechaza la hipótesis nula. Por lo que no es posible concluir que la distribución de ocupación sea homogénea entre los diferentes estados civiles"