Análisis descriptivos en estudios correlacionales

Autor/a
Afiliación

Cristopher Lino-Cruz

Universidad Peruana de Ciencias Aplicadas

Fecha de publicación

26 abril, 2025

1 Introducción

Esta guía tiene como objetivo brindar a los estudiantes una herramienta práctica para realizar el análisis descriptivo de ítems utilizando RStudio. Aprenderás a realizar una tabla de descripción de los participantes, calcular estadísticos descriptivos de los ítems (como media, desviación estándar, asimetría y curtosis), visualizar la distribución de respuestas mediante gráficos tipo Likert y evaluar la normalidad univariada y multivariada.

2 Configuración inicial

2.1 Limpiar el entorno de trabajo

Este comando elimina todos los objetos existentes en tu entorno de trabajo, asegurando que no interfieran con el nuevo análisis.

rm(list = ls())

2.2 Establecer el directorio de trabajo

Aquí definimos la carpeta donde están nuestros archivos. Es importante que el archivo df_final.xlsx esté dentro de esta carpeta.

Importante

💡 Cuando copies una ruta desde el explorador de Windows, recuerda cambiar las barras \ por /.

setwd("D:/07 UPC/2025-1/Producción científica/RStudio")  # Establecer el directorio deseado

3 Cargar librerías necesarias

#Procedemos a istalar librerías que se utilizarán
#install.packages("psych")
#install.packages("corrplot")
#install.packages("corpcor")
#install.packages("huge")

# Cargamos las librerías
library(dplyr)
Warning: package 'dplyr' was built under R version 4.4.3

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
library(readxl)
Warning: package 'readxl' was built under R version 4.4.3
library(ThesiStats)
library(PsyMetricTools)
library(openxlsx)
Warning: package 'openxlsx' was built under R version 4.4.3
library(psych)
Warning: package 'psych' was built under R version 4.4.3
library(corrplot)
corrplot 0.94 loaded
library(purrr)
library(broom)
Warning: package 'broom' was built under R version 4.4.3
library(corpcor)
library(huge)
Warning: package 'huge' was built under R version 4.4.2

4 Cargar la data frame final

Se carga la base de datos limpia exportada de la sesión anterior. Usamos la función read_excel() para leer el archivo df_final.xlsx. A ese archivo nuevamente le llamaremos df (abreviado de data frame). Posterior mente con la función glimpse() podremos ver la estructura de nuestra data frame.

df <- read_excel("Data_final 2.xlsx") 

glimpse(df)
Rows: 445
Columns: 39
$ Edad               <dbl> 21, 19, 21, 19, 23, 21, 43, 22, 42, 18, 34, 18, 34,…
$ Lugar_nacimiento   <chr> "Fuera de Lima", "Fuera de Lima", "Fuera de Lima", …
$ Estado_civil       <chr> "Soltero", "Soltero", "Soltero", "Soltero", "Solter…
$ Sexo               <chr> "Masculino", "Masculino", "Masculino", "Femenino", …
$ Orientación_sexual <chr> "Heterosexual", "Heterosexual", "Heterosexual", "He…
$ Vive_con           <chr> "Solo con mi madre", "Con mi madre y padre", "Solo …
$ Trabajo            <chr> "Tengo un trabajo temporal", "Estoy desempleado", "…
$ Nivel_educativo    <chr> "Secundaria incompleta", "Secundaria completa", "Un…
$ Horas_sueño        <dbl> 7, 8, 6, 6, 6, 6, 6, 8, 6, 5, 8, 5, 8, 7, 5, 6, 8, …
$ Sobrepeso          <chr> "No", "No", "Sí", "Sí", "Sí", "Sí", "No", "No", "Sí…
$ AFA1               <dbl> 3, 2, 2, 3, 3, 5, 1, 3, 4, 5, 4, 3, 5, 5, 1, 4, 2, …
$ AFA2               <dbl> 3, 3, 3, 4, 4, 5, 1, 3, 3, 4, 4, 3, 5, 3, 1, 3, 2, …
$ AFA3               <dbl> 2, 1, 2, 3, 3, 5, 1, 4, 4, 5, 4, 3, 5, 5, 1, 2, 3, …
$ AFA4               <dbl> 3, 2, 2, 3, 4, 5, 1, 2, 3, 4, 4, 3, 3, 2, 1, 2, 1, …
$ AFA5               <dbl> 2, 3, 2, 3, 5, 5, 1, 3, 5, 5, 5, 4, 5, 5, 1, 5, 2, …
$ AFA6               <dbl> 2, 3, 3, 4, 4, 5, 3, 1, 3, 5, 4, 4, 2, 3, 1, 4, 2, …
$ AFA7               <dbl> 4, 2, 1, 2, 5, 5, 3, 3, 5, 5, 4, 3, 5, 5, 1, 4, 2, …
$ AFA8               <dbl> 2, 3, 2, 3, 4, 5, 3, 3, 2, 5, 4, 3, 2, 3, 1, 3, 2, …
$ AFA9               <dbl> 2, 2, 2, 3, 3, 5, 1, 3, 5, 4, 4, 3, 5, 5, 1, 1, 2, …
$ AFA10              <dbl> 1, 2, 2, 2, 3, 5, 1, 1, 3, 3, 4, 3, 2, 2, 1, 1, 1, …
$ AFA11              <dbl> 1, 1, 1, 2, 1, 5, 1, 1, 2, 4, 4, 3, 2, 1, 1, 1, 1, …
$ AFA12              <dbl> 3, 1, 2, 2, 3, 5, 1, 1, 5, 5, 5, 3, 5, 5, 1, 3, 2, …
$ AFA13              <dbl> 4, 3, 3, 3, 4, 5, 1, 2, 5, 5, 5, 3, 5, 5, 1, 4, 2, …
$ AFA14              <dbl> 3, 3, 2, 3, 4, 5, 1, 1, 3, 5, 5, 4, 2, 5, 1, 4, 2, …
$ RAM1               <dbl> 2, 2, 4, 3, 3, 1, 2, 1, 1, 2, 2, 3, 1, 2, 1, 1, 1, …
$ RAM2               <dbl> 2, 1, 2, 2, 2, 3, 3, 5, 2, 1, 2, 2, 1, 2, 1, 1, 1, …
$ RAM3               <dbl> 2, 1, 4, 2, 3, 3, 3, 1, 1, 2, 2, 2, 1, 2, 2, 2, 1, …
$ RAM4               <dbl> 3, 2, 2, 3, 2, 1, 1, 1, 1, 2, 2, 2, 1, 2, 4, 1, 2, …
$ RAM5               <dbl> 3, 1, 2, 2, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, …
$ RAM6               <dbl> 2, 2, 4, 2, 2, 1, 3, 1, 1, 1, 2, 2, 1, 2, 1, 1, 2, …
$ RAM7               <dbl> 3, 1, 2, 2, 2, 1, 3, 1, 1, 1, 2, 2, 1, 2, 1, 1, 2, …
$ RAM8               <dbl> 3, 2, 3, 2, 2, 1, 2, 2, 1, 1, 2, 2, 1, 2, 1, 1, 2, …
$ RAM9               <dbl> 2, 2, 2, 3, 2, 1, 4, 2, 1, 2, 2, 2, 1, 2, 1, 1, 1, …
$ RAM10              <dbl> 1, 2, 3, 2, 2, 1, 3, 2, 2, 2, 2, 2, 1, 2, 1, 1, 1, …
$ SWLS1              <dbl> 2, 2, 2, 4, 2, 1, 3, 1, 1, 2, 2, 2, 1, 2, 1, 1, 2, …
$ SWLS2              <dbl> 2, 1, 2, 2, 2, 3, 2, 5, 1, 1, 2, 2, 1, 2, 2, 1, 2, …
$ SWLS3              <dbl> 2, 2, 4, 2, 2, 3, 3, 1, 1, 2, 2, 2, 1, 2, 2, 1, 2, …
$ SWLS4              <dbl> 3, 2, 2, 3, 2, 1, 4, 3, 1, 2, 2, 2, 1, 1, 4, 1, 2, …
$ SWLS5              <dbl> 3, 2, 2, 2, 2, 1, 2, 3, 1, 1, 2, 2, 1, 1, 2, 1, 2, …

5 Descripción de participantes

En ta sección se genera una tabla resumen con las variables sociodemográficas de interés. Esta tabla facilita la descripción de los participantes del estudio. Se utiliza la función generate_summary() para resumir variables como edad, sexo, lugar de nacimiento, estado civil, orientación sexual, entre otras.

Luego, la tabla generada se transforma en un formato adecuado para su exportación usando generate_table() y se guarda automáticamente en un archivo Excel (.xlsx) en la carpeta Output, con el nombre Tabla_Total.xlsx.

Tabla_Total <- generate_summary(
               data = df, 
               variables = c("Edad", "Lugar_nacimiento", "Estado_civil", "Sexo", 
                             "Orientación_sexual", "Vive_con", "Trabajo", 
                             "Nivel_educativo", "Horas_sueño", "Sobrepeso")
)

summary_Tabla_Total <- generate_table(Tabla_Total)
summary_Tabla_Total %>% openxlsx::write.xlsx(
  .,
  file = "Output2/Tabla_Total.xlsx",
  overwrite = TRUE
)

6 Realizamos sumatoria de los ítems

6.1 Importar archivo de texto

Se importa el archivo de texto con las indicaciones de los ítems con cada variable para codificar la sumatoria de las variables latentes.

texto <- readLines("Texto.txt", encoding = "UTF-8")
code <- ThesiStats::generate_code(texto, "df")
cat(code)
df <- df %>% 
  rowwise() %>% 
  mutate(Apoyo_familiar = sum(c_across(c(AFA1,AFA3,AFA5,AFA7,AFA9,AFA12,AFA13))),
         Apoyo_amigos = sum(c_across(c(AFA2,AFA4,AFA6,AFA8,AFA10,AFA11,AFA14))),
         Riesgo_adiccion = sum(c_across(c(RAM1,RAM2,RAM3,RAM4,RAM5,RAM6,RAM7,RAM8,RAM9,RAM10))),
         Satisfaccion_vida = sum(c_across(c(SWLS1,SWLS2,SWLS3,SWLS4,SWLS5)))) %>% 
  ungroup()

6.2 Creamos las columnas de puntajes totales

Copiamos y pegamos el code generado anteriormente.

df <- df %>% 
  rowwise() %>% 
  mutate(Apoyo_familiar = sum(c_across(c(AFA1,AFA3,AFA5,AFA7,AFA9,AFA12,AFA13))),
         Apoyo_amigos = sum(c_across(c(AFA2,AFA4,AFA6,AFA8,AFA10,AFA11,AFA14))),
         Riesgo_adiccion = sum(c_across(c(RAM1,RAM2,RAM3,RAM4,RAM5,RAM6,RAM7,RAM8,RAM9,RAM10))),
         Satisfaccion_vida = sum(c_across(c(SWLS1,SWLS2,SWLS3,SWLS4,SWLS5)))) %>% 
  ungroup()

7 Estadísticos descriptivos

Se obtiene un resumen estadístico de cada ítem utilizando la función describe() del paquete psych. Esta función proporciona indicadores clave como media, desviación estándar, asimetría (skew), curtosis, y el rango de respuestas, útiles para identificar ítems problemáticos o poco informativos.

# Seleccionamos solo las variables de puntajes totales
df_variables <- select(df, Apoyo_familiar:Satisfaccion_vida)

descriptivos <- describe(df_variables)
print(descriptivos)
                  vars   n  mean   sd median trimmed   mad min max range  skew
Apoyo_familiar       1 445 23.53 7.20     23   23.76  7.41   7  35    28 -0.19
Apoyo_amigos         2 445 22.58 7.07     22   22.66  7.41   7  35    28 -0.08
Riesgo_adiccion      3 445 22.05 8.09     22   21.72 10.38  10  50    40  0.57
Satisfaccion_vida    4 445 11.20 4.61     11   10.96  5.93   5  25    20  0.34
                  kurtosis   se
Apoyo_familiar       -0.70 0.34
Apoyo_amigos         -0.61 0.34
Riesgo_adiccion       0.42 0.38
Satisfaccion_vida    -0.48 0.22
# Redondear los decimales
descriptivos <- descriptivos %>% 
  mutate_if(is.numeric, ~ round(., 2))

#Guardar en una tabla
openxlsx::write.xlsx(descriptivos, 
                     file = "Output2/Table_descriptive.xlsx", overwrite = T)

8 Normalidad univariada

En este bloque de código se evalúa la normalidad univariada de las variables compuestas utilizando el test de Shapiro-Wilk:

# Aplicar Shapiro-Wilk
tabla_shapiro <- map_df(df_variables, ~ tidy(shapiro.test(.x)), .id = "Variable")

# Añadir columna de interpretación
tabla_shapiro <- tabla_shapiro %>%
  mutate(
    Normalidad = if_else(p.value >= 0.05, "Sí", "No")  # p >= .05 normalidad
  )

# Tabla de resultados
Normalidad <- tabla_shapiro %>% 
              select(Variable, statistic, p.value, Normalidad)

print(Normalidad)
# A tibble: 4 × 4
  Variable          statistic  p.value Normalidad
  <chr>                 <dbl>    <dbl> <chr>     
1 Apoyo_familiar        0.970 7.55e- 8 No        
2 Apoyo_amigos          0.979 4.63e- 6 No        
3 Riesgo_adiccion       0.950 3.75e-11 No        
4 Satisfaccion_vida     0.941 2.51e-12 No        
#Guardar en una tabla
openxlsx::write.xlsx(Normalidad, 
                     file = "Output2/Normalidad.xlsx", overwrite = T)

9 Normalidad multivariada

En este bloque se evalúa la normalidad multivariada de las variables compuestas mediante el test de Mardia, el cual analiza la asimetría y curtosis multivariada. Se utilizaron las siguientes funciones:

  • mardia_test(): Permite detectar desviaciones respecto a la normalidad cuando se analizan múltiples variables al mismo tiempo.
  • Multivariate_plot(): Genera un gráfico Q-Q de las distancias de Mahalanobis comparadas con los cuantiles teóricos de una distribución chi-cuadrado. Si los puntos del gráfico se alinean con la diagonal roja, se considera que los datos cumplen con la normalidad multivariada. En caso contrario (como suele suceder con ítems tipo Likert), se interpreta como una violación de este supuesto.
mardia_test(df_variables)
             Test  Statistic  p.value Result
1 Mardia Skewness 101.049187 p < .001     NO
2 Mardia Kurtosis   5.314396 p < .001     NO
Normalidad <- Multivariate_plot(df_variables, 
                                xmin = 10, 
                                xmax = 20, 
                                ymin = 0, 
                                ymax = 3)

Adjuntando el paquete: 'ggplot2'
The following objects are masked from 'package:psych':

    %+%, alpha

Adjuntando el paquete: 'gridExtra'
The following object is masked from 'package:dplyr':

    combine
Warning: package 'gtable' was built under R version 4.4.3
print(Normalidad)

# Guardar como imagen
ggsave("Output2/Figura_Normalidad.jpg", plot = Normalidad, 
       width = 8, height = 6, dpi = 800)

10 Trasnformaciones estadísticas

En este bloque de código se realiza una transformación no-paranormal (npn) de las variables compuestas utilizando la función huge.npn() del paquete huge. Esta transformación ajusta los datos para aproximarlos a una estructura de normalidad multivariada, sin alterar el orden de los valores originales.

# transformar datos no parametricos en parametricos
library(huge)
data_npn <- huge.npn(df_variables, npn.func = "shrinkage", 
                     npn.thresh = NULL, verbose = TRUE)
Conducting the nonparanormal (npn) transformation via shrunkun ECDF....done.
df_transformed <- as.data.frame(apply(data_npn, 2, 
                                      function(x) as.numeric(round(x, digits = 2))))

11 Correlación

En este bloque de código se calcula la matriz de correlaciones entre las variables transformadas utilizando la función cor(), basada en correlaciones de Pearson. Posteriormente, se utiliza corrplot() para visualizar la matriz en forma gráfica, representando la fuerza de las asociaciones mediante círculos cuyo tamaño y color indican la magnitud y dirección de las correlaciones.

Además, se verifica si la matriz de correlaciones es definida positiva utilizando la función is.positive.definite() del paquete corpcor. Este paso es importante para confirmar que la matriz es adecuada para procedimientos posteriores como el ajuste de redes gaussianas. Finalmente guardamos la figura.

# Calcular la matriz de correlaciones
M <- cor(df_transformed)
corrplot(M, method = "circle", 
         type = "lower",
         tl.col = "black", 
         tl.srt = 45, 
         number.cex = 0.75,
         addCoef.col = "black") 

# Verificar si la matriz es definida positiva
library(corpcor)
is.positive.definite(M) # TRUE
[1] TRUE
# Guardamos la figura
jpeg("Output2/Figura_Corrplot.jpg", width = 10, 
     height = 8, units = "in", res = 800)

corrplot(M, method = "circle", 
         type = "lower",
         tl.col = "black", 
         tl.srt = 45, 
         number.cex = 0.75,
         addCoef.col = "black") 

dev.off()
png 
  2 

12 Referencias

Revelle, W. (2024). psych: Procedures for Psychological, Psychometric, and Personality Research (v2.4.1) [R package]. Northwestern University. https://CRAN.R-project.org/package=psych

Ventura-León, J. (2024). PsyMetricTools: Psychometric and Statistical Analysis Tools (v1.0.0) [R package]. https://github.com/jventurealn/PsyMetricTools

Ventura-León, J. (2024). ThesiStats: Thesis Analysis Tools for Statistical Computing (v1.0.0) [R package]. https://github.com/jventurealn/ThesiStats

Walker, A. (2023). openxlsx: Read, Write and Edit xlsx Files (v4.2.5.2) [R package]. https://CRAN.R-project.org/package=openxlsx

Wei, T., & Simko, V. (2021). corrplot: Visualization of a Correlation Matrix (v0.92) [R package]. https://CRAN.R-project.org/package=corrplot

Wickham, H., François, R., Henry, L., Müller, K., & Vaughan, D. (2023). dplyr: A Grammar of Data Manipulation (v1.1.4) [R package]. Posit Software. https://dplyr.tidyverse.org

Wickham, H., & Bryan, J. (2023). readxl: Read Excel Files (v1.4.3) [R package]. Posit Software. https://readxl.tidyverse.org

Wickham, H., Hester, J., & Bryan, J. (2024). readr: Read Rectangular Text Data (v2.1.5) [R package]. Posit Software. https://readr.tidyverse.org