1 Introducción

¡Bienvenido a este tutorial! El objetivo es guiarte a través de los pasos fundamentales para manejar y manipular un conjunto de datos en R utilizando RStudio. Aprenderás a:

  1. Crear un entorno de trabajo organizado con un Proyecto de RStudio.
  2. Cargar y explorar un conjunto de datos.
  3. Manipular los datos utilizando el paquete dplyr.
  • Utilizaremos la base de datos llamada CAP.xlxs.

2 Creación de un Proyecto en RStudio

El primer paso para cualquier análisis es organizar tus archivos. Un Proyecto de RStudio es la mejor manera de hacerlo, ya que agrupa todos tus scripts, datos y resultados en una sola carpeta.

2.1 Pasos para crear un proyecto:

  1. Abre RStudio.
  2. Ve al menú File -> New Project….
  3. Selecciona New Directory.
  4. Selecciona New Project.
  5. En “Directory name”, escribe un nombre para tu proyecto, por ejemplo, Analisis_Descriptivo.
  6. En “Create project as subdirectory of”, elige una ubicación fácil de encontrar (como tu Escritorio o la carpeta de Documentos).
  7. Haz clic en Create Project.

¡Listo! Ahora te encuentras dentro de tu nuevo proyecto. Todos los archivos que guardes se almacenarán en esta carpeta.


3 Carga de la base de datos

Para este tutorial, trabajaremos con un archivo de Excel (.xlsx) llamado CAP.xlsx. Asegúrate de que este archivo se encuentre en la misma carpeta que tu proyecto de RStudio.

3.1 Instalar y cargar la librería readxl

Para leer archivos de Excel en R, necesitamos una librería especializada. Una de las más populares y eficientes es readxl. Si no la tienes instalada, el siguiente código lo hará por ti.

# Instalar si no está presente
if (!require(readxl)) {
  install.packages("readxl")
}

# Cargar la librería
library(readxl)

3.2 Cargar el archivo CAP.xlsx a R

Ahora, usaremos la función read_excel() de la librería readxl para cargar nuestros datos en un objeto llamado datos.

# Usamos read_excel) para leer el archivo
# R buscará el archivo en el directorio de tu proyecto actual
datos <- read_excel("CAP.xlsx")

4 Exploración Inicial de los Datos

Una vez cargados los datos, es fundamental explorarlos para entender su estructura y contenido. Este paso nos ayuda a identificar posibles problemas como valores faltantes o tipos de datos incorrectos.

4.1 Vistazo rápido con head() y tail

La función head() nos muestra las primeras 6 filas del conjunto de datos. Es la forma más rápida de confirmar que los datos se han cargado como esperábamos.

# Muestra las primeras 6 filas del data frame 'datos'
head(datos)
## # A tibble: 6 × 86
##      id part_prev municipio  edad genero nivel_edu enf_cro tipo_enfcro  ninguna
##   <dbl>     <dbl>     <dbl> <dbl>  <dbl>     <dbl>   <dbl> <chr>          <dbl>
## 1     1         0         6    52      0         0       0 Ninguna            1
## 2     2         1         6    50      1         1       1 Diabetes           0
## 3     3         0         6    27      0         4       0 Ninguna            1
## 4     4         0         6    50      1         3       0 Ninguna            1
## 5     5         0         6    47      0         3       1 Hipertensión       0
## 6     6         0         6    47      1         2       1 Hipertensión       0
## # ℹ 77 more variables: hipertension <dbl>, diabetes <dbl>, epoc <dbl>,
## #   renal <dbl>, artritis <dbl>, cardiopatia <dbl>, hipotiroidismo <dbl>,
## #   glaucoma <dbl>, lupus <dbl>, ulcera_venosa <dbl>,
## #   `Otras enfermedades cronicas, especifique` <chr>, area <dbl>, hijxs <dbl>,
## #   nucleo <dbl>, empleo <dbl>, ocupacion <dbl>, ingreso <dbl>, prev_per <dbl>,
## #   rec_apoyo <dbl>, satisfaccion <dbl>, prev_fam <dbl>, mortalidad <dbl>,
## #   c1 <dbl>, c2 <dbl>, c3 <dbl>, c4 <dbl>, c5 <dbl>, c6 <dbl>, c7 <dbl>, …

La función tail() nos muestra las últimas 6 filas del conjunto de datos.

# Muestra las últimas 6 filas del data frame 'datos'
tail(datos)
## # A tibble: 6 × 86
##      id part_prev municipio  edad genero nivel_edu enf_cro tipo_enfcro ninguna
##   <dbl>     <dbl>     <dbl> <dbl>  <dbl>     <dbl>   <dbl> <chr>         <dbl>
## 1   510         1         3    27      0         3       1 Ninguna           1
## 2   511         0         3    31      0         2       0 Ninguna           1
## 3   512         0         3    43      1         4       0 Ninguna           1
## 4   513         0         3    56      0         2       0 Ninguna           1
## 5   514         0         3    43      1         1       0 Ninguna           1
## 6   515         0         3    54      1         3       1 Diabetes          0
## # ℹ 77 more variables: hipertension <dbl>, diabetes <dbl>, epoc <dbl>,
## #   renal <dbl>, artritis <dbl>, cardiopatia <dbl>, hipotiroidismo <dbl>,
## #   glaucoma <dbl>, lupus <dbl>, ulcera_venosa <dbl>,
## #   `Otras enfermedades cronicas, especifique` <chr>, area <dbl>, hijxs <dbl>,
## #   nucleo <dbl>, empleo <dbl>, ocupacion <dbl>, ingreso <dbl>, prev_per <dbl>,
## #   rec_apoyo <dbl>, satisfaccion <dbl>, prev_fam <dbl>, mortalidad <dbl>,
## #   c1 <dbl>, c2 <dbl>, c3 <dbl>, c4 <dbl>, c5 <dbl>, c6 <dbl>, c7 <dbl>, …

4.2 Estructura del objeto con str()

La función str() (de structure) nos da un resumen compacto de la estructura del data.frame. Es extremadamente útil para ver:

  • El número total de observaciones (filas) y variables (columnas).
  • El nombre de cada columna.
  • El tipo de dato de cada columna (int para enteros, num para numéricos, chr para caracteres, etc.).
  • Una vista previa de los primeros valores de cada columna.
# Muestra la estructura del objeto 'datos'
str(datos)
## tibble [515 × 86] (S3: tbl_df/tbl/data.frame)
##  $ id                                      : num [1:515] 1 2 3 4 5 6 7 8 9 10 ...
##  $ part_prev                               : num [1:515] 0 1 0 0 0 0 1 0 1 0 ...
##  $ municipio                               : num [1:515] 6 6 6 6 6 6 6 6 6 6 ...
##  $ edad                                    : num [1:515] 52 50 27 50 47 47 33 21 37 29 ...
##  $ genero                                  : num [1:515] 0 1 0 1 0 1 0 0 1 1 ...
##  $ nivel_edu                               : num [1:515] 0 1 4 3 3 2 4 3 2 4 ...
##  $ enf_cro                                 : num [1:515] 0 1 0 0 1 1 0 0 1 0 ...
##  $ tipo_enfcro                             : chr [1:515] "Ninguna" "Diabetes" "Ninguna" "Ninguna" ...
##  $ ninguna                                 : num [1:515] 1 0 1 1 0 0 1 1 0 1 ...
##  $ hipertension                            : num [1:515] 0 0 0 0 1 1 0 0 1 0 ...
##  $ diabetes                                : num [1:515] 0 1 0 0 0 1 0 0 0 0 ...
##  $ epoc                                    : num [1:515] 0 0 0 0 0 0 0 0 0 0 ...
##  $ renal                                   : num [1:515] 0 0 0 0 0 0 0 0 0 0 ...
##  $ artritis                                : num [1:515] 0 0 0 0 0 0 0 0 0 0 ...
##  $ cardiopatia                             : num [1:515] 0 0 0 0 0 0 0 0 0 0 ...
##  $ hipotiroidismo                          : num [1:515] 0 0 0 0 0 0 0 0 0 0 ...
##  $ glaucoma                                : num [1:515] 0 0 0 0 0 0 0 0 0 0 ...
##  $ lupus                                   : num [1:515] 0 0 0 0 0 0 0 0 0 0 ...
##  $ ulcera_venosa                           : num [1:515] 0 0 0 0 0 0 0 0 0 0 ...
##  $ Otras enfermedades cronicas, especifique: chr [1:515] NA NA NA NA ...
##  $ area                                    : num [1:515] 1 0 0 1 1 0 1 0 1 1 ...
##  $ hijxs                                   : num [1:515] 1 1 1 0 1 1 1 1 1 1 ...
##  $ nucleo                                  : num [1:515] 5 2 5 3 4 5 3 2 3 3 ...
##  $ empleo                                  : num [1:515] 0 1 0 1 1 0 1 0 1 1 ...
##  $ ocupacion                               : num [1:515] 0 1 0 4 4 0 3 0 1 1 ...
##  $ ingreso                                 : num [1:515] 1 0 2 1 0 1 3 1 2 0 ...
##  $ prev_per                                : num [1:515] 0 3 0 0 0 0 0 0 1 1 ...
##  $ rec_apoyo                               : num [1:515] 3 0 3 3 3 3 3 3 2 2 ...
##  $ satisfaccion                            : num [1:515] 5 5 5 5 5 5 5 5 3 4 ...
##  $ prev_fam                                : num [1:515] 2 0 0 0 0 3 0 3 1 1 ...
##  $ mortalidad                              : num [1:515] 0 0 0 0 0 0 0 0 1 0 ...
##  $ c1                                      : num [1:515] 3 1 1 1 1 1 1 1 1 1 ...
##  $ c2                                      : num [1:515] 2 1 1 1 1 1 1 1 1 1 ...
##  $ c3                                      : num [1:515] 3 1 3 1 1 3 1 3 3 1 ...
##  $ c4                                      : num [1:515] 1 1 1 1 1 1 1 3 3 1 ...
##  $ c5                                      : num [1:515] 1 3 1 1 3 1 3 3 3 2 ...
##  $ c6                                      : num [1:515] 1 1 2 1 1 2 1 2 2 1 ...
##  $ c7                                      : num [1:515] 3 3 2 2 3 1 1 3 1 1 ...
##  $ c8                                      : num [1:515] 1 1 1 1 1 1 1 1 1 1 ...
##  $ c9                                      : num [1:515] 1 1 2 1 1 1 1 1 1 1 ...
##  $ c10                                     : num [1:515] 2 1 1 2 1 1 1 1 1 1 ...
##  $ a1                                      : num [1:515] 5 4 5 5 4 3 4 3 2 5 ...
##  $ a2                                      : num [1:515] 5 5 5 5 4 3 4 3 5 5 ...
##  $ a3                                      : num [1:515] 1 2 5 5 3 1 4 1 2 4 ...
##  $ a4                                      : num [1:515] 5 5 5 5 4 5 4 5 5 4 ...
##  $ a5                                      : num [1:515] 1 3 5 1 4 4 4 1 3 4 ...
##  $ p1                                      : num [1:515] 5 3 5 5 1 4 3 3 3 2 ...
##  $ p2                                      : num [1:515] 2 0 3 3 0 2 0 2 2 0 ...
##  $ p3                                      : num [1:515] 3 0 2 3 0 3 0 2 2 0 ...
##  $ p4                                      : num [1:515] 5 1 5 3 1 3 1 3 3 1 ...
##  $ p5                                      : num [1:515] 5 1 3 2 3 3 3 2 5 3 ...
##  $ dosis                                   : num [1:515] 3 3 4 3 2 2 2 1 4 3 ...
##  $ razon_nv                                : num [1:515] 5 6 1 6 6 6 6 6 1 6 ...
##  $ fuentes                                 : chr [1:515] "Periódico, Televisión, Radio, Otro medio, especificar" "Televisión, Redes sociales: WhatsApp, Facebook, etc." "Televisión, Redes sociales: WhatsApp, Facebook, etc., Radio, Páginas de internet" "Periódico, Televisión, Páginas de internet" ...
##  $ periodico                               : num [1:515] 1 0 0 1 0 1 0 0 1 0 ...
##  $ television                              : num [1:515] 1 1 1 1 0 1 1 1 1 0 ...
##  $ redes_sociales                          : num [1:515] 0 1 1 0 1 0 1 1 0 1 ...
##  $ personal_salud                          : num [1:515] 0 0 0 0 0 0 0 0 0 0 ...
##  $ radio                                   : num [1:515] 1 0 1 0 0 1 0 0 1 0 ...
##  $ paginas_internet                        : num [1:515] 0 0 1 1 0 0 0 0 0 1 ...
##  $ escuela                                 : num [1:515] 1 0 0 0 0 0 0 0 0 0 ...
##  $ mensajes                                : num [1:515] 1 1 1 1 1 1 1 1 1 1 ...
##  $ patrocinio                              : num [1:515] 5 2 6 1 1 1 2 1 2 1 ...
##  $ mensajes_rec                            : chr [1:515] "Uso de la mascarilla, El distanciamiento social, Ponerse la vacuna" "Uso de la mascarilla, Lavado de manos" "Uso de la mascarilla, El distanciamiento social, Lavado de manos" "Uso de la mascarilla, El distanciamiento social, Ponerse la vacuna" ...
##  $ uso_de_mascarilla                       : num [1:515] 1 1 1 1 0 0 0 0 1 1 ...
##  $ distanciamiento_social                  : num [1:515] 1 0 1 1 1 0 1 0 1 0 ...
##  $ lavado_de_manos                         : num [1:515] 0 1 1 0 1 0 1 0 1 1 ...
##  $ ponerse_la_vacuna                       : num [1:515] 1 0 0 1 1 0 0 0 0 1 ...
##  $ no_recuerdo                             : num [1:515] 0 0 0 0 0 0 0 1 0 0 ...
##  $ todas                                   : num [1:515] 0 0 0 0 0 1 0 0 0 0 ...
##  $ otros...71                              : num [1:515] 0 0 0 0 0 0 0 0 0 0 ...
##  $ No_he_escuchado                         : num [1:515] 0 0 0 0 0 0 0 0 0 0 ...
##  $ mitos                                   : chr [1:515] "El virus se transmite por el agua por eso no se deben usar las piscinas, El virus se transmite en las suelas de"| __truncated__ "Otros" "Se debe rociar desinfectantes en la ropa y el cuerpo para protegerse del virus, No se debe vacunar a las person"| __truncated__ "El virus se transmite por el agua por eso no se deben usar las piscinas, El virus se transmite en las suelas de"| __truncated__ ...
##  $ transmite_por_el_agua                   : num [1:515] 1 0 0 1 0 1 0 1 1 0 ...
##  $ transmite_en_las_suelas                 : num [1:515] 1 0 0 1 0 1 0 1 1 0 ...
##  $ rociar_desinfectantes                   : num [1:515] 1 0 1 1 0 1 0 1 1 0 ...
##  $ beben_alcohol                           : num [1:515] 0 0 0 1 0 0 0 0 0 0 ...
##  $ pueden_dejar_de_aplicar                 : num [1:515] 1 0 0 0 0 0 0 1 0 0 ...
##  $ no_se_debe_vacunar                      : num [1:515] 0 0 1 1 1 0 1 0 0 1 ...
##  $ producen_esterilidad                    : num [1:515] 0 0 0 0 0 0 1 0 0 0 ...
##  $ producen_homosexualidad                 : num [1:515] 0 1 0 0 0 0 0 0 0 0 ...
##  $ inyectan_el_virus                       : num [1:515] 0 0 1 1 0 1 0 0 0 0 ...
##  $ antibioticos_son_buenos                 : num [1:515] 0 0 0 1 0 1 0 1 1 0 ...
##  $ vitaminas_y_minerales                   : num [1:515] 0 0 0 0 0 0 0 1 1 0 ...
##  $ otros...85                              : num [1:515] 0 1 0 0 0 0 0 0 0 0 ...
##  $ entrevistadoras                         : num [1:515] 2 1 2 2 1 2 1 2 2 1 ...

5 Otras funciones importantes para explorar los datos son:

  • dim(datos)
  • names(datos)
  • rownames(datos)
  • colnames(datos)
  • lenght(datos)
  • glimpse(datos)
  • View(datos)

5.1 Resumen estadístico con summary()

La función summary() proporciona un resumen estadístico para cada columna.

  • Para variables numéricas, muestra la media, mediana, los cuartiles (25% y 75%), el valor mínimo y el máximo. También indica si hay valores NA (faltantes).
  • Para variables categóricas (de tipo character), muestra la longitud, la clase y el modo del vector.
# Genera un resumen estadístico de cada columna en 'datos'
summary(datos)
##        id          part_prev         municipio          edad      
##  Min.   :  1.0   Min.   :0.00000   Min.   :1.000   Min.   :19.00  
##  1st Qu.:129.5   1st Qu.:0.00000   1st Qu.:3.500   1st Qu.:30.00  
##  Median :258.0   Median :0.00000   Median :6.000   Median :40.00  
##  Mean   :258.0   Mean   :0.08932   Mean   :4.849   Mean   :42.37  
##  3rd Qu.:386.5   3rd Qu.:0.00000   3rd Qu.:6.000   3rd Qu.:55.00  
##  Max.   :515.0   Max.   :1.00000   Max.   :7.000   Max.   :89.00  
##                                                                   
##      genero        nivel_edu       enf_cro      tipo_enfcro       
##  Min.   :0.000   Min.   :0.00   Min.   :0.000   Length:515        
##  1st Qu.:0.000   1st Qu.:2.00   1st Qu.:0.000   Class :character  
##  Median :0.000   Median :3.00   Median :0.000   Mode  :character  
##  Mean   :0.435   Mean   :3.21   Mean   :0.334                     
##  3rd Qu.:1.000   3rd Qu.:4.00   3rd Qu.:1.000                     
##  Max.   :1.000   Max.   :6.00   Max.   :2.000                     
##                                                                   
##     ninguna        hipertension       diabetes           epoc         
##  Min.   :0.0000   Min.   :0.0000   Min.   :0.0000   Min.   :0.000000  
##  1st Qu.:0.0000   1st Qu.:0.0000   1st Qu.:0.0000   1st Qu.:0.000000  
##  Median :1.0000   Median :0.0000   Median :0.0000   Median :0.000000  
##  Mean   :0.6757   Mean   :0.2563   Mean   :0.1165   Mean   :0.007767  
##  3rd Qu.:1.0000   3rd Qu.:1.0000   3rd Qu.:0.0000   3rd Qu.:0.000000  
##  Max.   :1.0000   Max.   :1.0000   Max.   :1.0000   Max.   :1.000000  
##                                                                       
##      renal            artritis        cardiopatia       hipotiroidismo    
##  Min.   :0.00000   Min.   :0.00000   Min.   :0.000000   Min.   :0.000000  
##  1st Qu.:0.00000   1st Qu.:0.00000   1st Qu.:0.000000   1st Qu.:0.000000  
##  Median :0.00000   Median :0.00000   Median :0.000000   Median :0.000000  
##  Mean   :0.01942   Mean   :0.01942   Mean   :0.001942   Mean   :0.001942  
##  3rd Qu.:0.00000   3rd Qu.:0.00000   3rd Qu.:0.000000   3rd Qu.:0.000000  
##  Max.   :1.00000   Max.   :1.00000   Max.   :1.000000   Max.   :1.000000  
##                                                                           
##     glaucoma            lupus          ulcera_venosa     
##  Min.   :0.000000   Min.   :0.000000   Min.   :0.000000  
##  1st Qu.:0.000000   1st Qu.:0.000000   1st Qu.:0.000000  
##  Median :0.000000   Median :0.000000   Median :0.000000  
##  Mean   :0.001946   Mean   :0.001942   Mean   :0.001942  
##  3rd Qu.:0.000000   3rd Qu.:0.000000   3rd Qu.:0.000000  
##  Max.   :1.000000   Max.   :1.000000   Max.   :1.000000  
##  NA's   :1                                               
##  Otras enfermedades cronicas, especifique      area            hijxs      
##  Length:515                               Min.   :0.0000   Min.   :0.000  
##  Class :character                         1st Qu.:0.0000   1st Qu.:0.000  
##  Mode  :character                         Median :1.0000   Median :1.000  
##                                           Mean   :0.6408   Mean   :0.635  
##                                           3rd Qu.:1.0000   3rd Qu.:1.000  
##                                           Max.   :1.0000   Max.   :1.000  
##                                                                           
##      nucleo           empleo        ocupacion         ingreso      
##  Min.   :  1.00   Min.   :0.000   Min.   : 0.000   Min.   :0.0000  
##  1st Qu.:  3.00   1st Qu.:1.000   1st Qu.: 1.000   1st Qu.:0.0000  
##  Median :  4.00   Median :1.000   Median : 3.000   Median :1.0000  
##  Mean   :  5.67   Mean   :1.021   Mean   : 3.771   Mean   :0.9223  
##  3rd Qu.:  5.00   3rd Qu.:1.000   3rd Qu.: 6.000   3rd Qu.:2.0000  
##  Max.   :999.00   Max.   :3.000   Max.   :10.000   Max.   :4.0000  
##                                                                    
##     prev_per        rec_apoyo       satisfaccion      prev_fam     
##  Min.   :0.0000   Min.   :  0.00   Min.   :2.000   Min.   :0.0000  
##  1st Qu.:0.0000   1st Qu.:  1.00   1st Qu.:3.000   1st Qu.:0.0000  
##  Median :0.0000   Median :  3.00   Median :5.000   Median :0.0000  
##  Mean   :0.4738   Mean   : 29.43   Mean   :4.278   Mean   :0.7709  
##  3rd Qu.:1.0000   3rd Qu.:  3.00   3rd Qu.:5.000   3rd Qu.:1.0000  
##  Max.   :3.0000   Max.   :999.00   Max.   :5.000   Max.   :3.0000  
##                                                                    
##    mortalidad            c1              c2              c3       
##  Min.   :0.00000   Min.   :1.000   Min.   :1.000   Min.   :1.000  
##  1st Qu.:0.00000   1st Qu.:1.000   1st Qu.:1.000   1st Qu.:1.000  
##  Median :0.00000   Median :1.000   Median :1.000   Median :1.000  
##  Mean   :0.04466   Mean   :1.066   Mean   :1.151   Mean   :1.645  
##  3rd Qu.:0.00000   3rd Qu.:1.000   3rd Qu.:1.000   3rd Qu.:2.000  
##  Max.   :1.00000   Max.   :3.000   Max.   :3.000   Max.   :3.000  
##                                                                   
##        c4              c5              c6              c7             c8       
##  Min.   :1.000   Min.   :1.000   Min.   :1.000   Min.   :1.00   Min.   :1.000  
##  1st Qu.:1.000   1st Qu.:1.000   1st Qu.:1.000   1st Qu.:1.00   1st Qu.:1.000  
##  Median :1.000   Median :2.000   Median :1.000   Median :2.00   Median :1.000  
##  Mean   :1.171   Mean   :2.155   Mean   :1.301   Mean   :1.94   Mean   :1.037  
##  3rd Qu.:1.000   3rd Qu.:3.000   3rd Qu.:2.000   3rd Qu.:3.00   3rd Qu.:1.000  
##  Max.   :3.000   Max.   :3.000   Max.   :3.000   Max.   :3.00   Max.   :3.000  
##                                                                                
##        c9             c10              a1              a2              a3      
##  Min.   :1.000   Min.   :1.000   Min.   :2.000   Min.   :1.000   Min.   :1.00  
##  1st Qu.:1.000   1st Qu.:1.000   1st Qu.:3.000   1st Qu.:3.000   1st Qu.:1.00  
##  Median :1.000   Median :2.000   Median :4.000   Median :4.000   Median :2.00  
##  Mean   :1.091   Mean   :2.062   Mean   :3.986   Mean   :4.033   Mean   :2.25  
##  3rd Qu.:1.000   3rd Qu.:3.000   3rd Qu.:5.000   3rd Qu.:5.000   3rd Qu.:3.00  
##  Max.   :3.000   Max.   :3.000   Max.   :5.000   Max.   :5.000   Max.   :5.00  
##                                                                                
##        a4              a5             p1              p2              p3       
##  Min.   :1.000   Min.   :1.00   Min.   :0.000   Min.   :0.000   Min.   :0.000  
##  1st Qu.:3.000   1st Qu.:2.00   1st Qu.:1.000   1st Qu.:0.500   1st Qu.:0.000  
##  Median :4.000   Median :3.00   Median :2.000   Median :1.000   Median :1.000  
##  Mean   :3.808   Mean   :2.75   Mean   :2.468   Mean   :1.579   Mean   :1.524  
##  3rd Qu.:5.000   3rd Qu.:3.00   3rd Qu.:4.000   3rd Qu.:3.000   3rd Qu.:3.000  
##  Max.   :5.000   Max.   :5.00   Max.   :5.000   Max.   :5.000   Max.   :5.000  
##                                                                                
##        p4              p5            dosis          razon_nv     
##  Min.   :0.000   Min.   :0.000   Min.   :0.000   Min.   : 1.000  
##  1st Qu.:1.000   1st Qu.:2.000   1st Qu.:2.000   1st Qu.: 5.000  
##  Median :3.000   Median :3.000   Median :2.000   Median : 5.000  
##  Mean   :2.936   Mean   :3.103   Mean   :2.355   Mean   : 4.746  
##  3rd Qu.:5.000   3rd Qu.:4.000   3rd Qu.:3.000   3rd Qu.: 6.000  
##  Max.   :5.000   Max.   :5.000   Max.   :4.000   Max.   :11.000  
##                                                                  
##    fuentes            periodico        television     redes_sociales  
##  Length:515         Min.   :0.0000   Min.   :0.0000   Min.   :0.0000  
##  Class :character   1st Qu.:0.0000   1st Qu.:1.0000   1st Qu.:1.0000  
##  Mode  :character   Median :0.0000   Median :1.0000   Median :1.0000  
##                     Mean   :0.1107   Mean   :0.8408   Mean   :0.7592  
##                     3rd Qu.:0.0000   3rd Qu.:1.0000   3rd Qu.:1.0000  
##                     Max.   :1.0000   Max.   :1.0000   Max.   :1.0000  
##                                                                       
##  personal_salud       radio        paginas_internet    escuela        
##  Min.   :0.0000   Min.   :0.0000   Min.   :0.0000   Min.   :0.000000  
##  1st Qu.:0.0000   1st Qu.:0.0000   1st Qu.:0.0000   1st Qu.:0.000000  
##  Median :0.0000   Median :0.0000   Median :0.0000   Median :0.000000  
##  Mean   :0.1243   Mean   :0.1786   Mean   :0.2233   Mean   :0.001942  
##  3rd Qu.:0.0000   3rd Qu.:0.0000   3rd Qu.:0.0000   3rd Qu.:0.000000  
##  Max.   :1.0000   Max.   :1.0000   Max.   :1.0000   Max.   :1.000000  
##                                                                       
##     mensajes        patrocinio    mensajes_rec       uso_de_mascarilla
##  Min.   :0.0000   Min.   :1.000   Length:515         Min.   :0.0000   
##  1st Qu.:0.0000   1st Qu.:1.000   Class :character   1st Qu.:0.0000   
##  Median :1.0000   Median :7.000   Mode  :character   Median :0.0000   
##  Mean   :0.8252   Mean   :4.297                      Mean   :0.4136   
##  3rd Qu.:1.0000   3rd Qu.:7.000                      3rd Qu.:1.0000   
##  Max.   :2.0000   Max.   :7.000                      Max.   :1.0000   
##                                                                       
##  distanciamiento_social lavado_de_manos  ponerse_la_vacuna  no_recuerdo      
##  Min.   :0.0000         Min.   :0.0000   Min.   :0.0000    Min.   :0.000000  
##  1st Qu.:0.0000         1st Qu.:0.0000   1st Qu.:0.0000    1st Qu.:0.000000  
##  Median :1.0000         Median :1.0000   Median :0.0000    Median :0.000000  
##  Mean   :0.5592         Mean   :0.6155   Mean   :0.2621    Mean   :0.009709  
##  3rd Qu.:1.0000         3rd Qu.:1.0000   3rd Qu.:1.0000    3rd Qu.:0.000000  
##  Max.   :1.0000         Max.   :1.0000   Max.   :1.0000    Max.   :1.000000  
##                                                                              
##      todas          otros...71       No_he_escuchado      mitos          
##  Min.   :0.0000   Min.   :0.000000   Min.   :0.00000   Length:515        
##  1st Qu.:0.0000   1st Qu.:0.000000   1st Qu.:0.00000   Class :character  
##  Median :0.0000   Median :0.000000   Median :0.00000   Mode  :character  
##  Mean   :0.2854   Mean   :0.007767   Mean   :0.06408                     
##  3rd Qu.:1.0000   3rd Qu.:0.000000   3rd Qu.:0.00000                     
##  Max.   :1.0000   Max.   :1.000000   Max.   :1.00000                     
##                                                                          
##  transmite_por_el_agua transmite_en_las_suelas rociar_desinfectantes
##  Min.   :0.0000        Min.   :0.0000          Min.   :0.0000       
##  1st Qu.:0.0000        1st Qu.:1.0000          1st Qu.:0.0000       
##  Median :1.0000        Median :1.0000          Median :1.0000       
##  Mean   :0.7184        Mean   :0.8544          Mean   :0.6175       
##  3rd Qu.:1.0000        3rd Qu.:1.0000          3rd Qu.:1.0000       
##  Max.   :1.0000        Max.   :1.0000          Max.   :1.0000       
##                                                                     
##  beben_alcohol    pueden_dejar_de_aplicar no_se_debe_vacunar
##  Min.   :0.0000   Min.   :0.0000          Min.   :0.0000    
##  1st Qu.:0.0000   1st Qu.:0.0000          1st Qu.:0.0000    
##  Median :0.0000   Median :0.0000          Median :0.0000    
##  Mean   :0.1981   Mean   :0.1359          Mean   :0.1495    
##  3rd Qu.:0.0000   3rd Qu.:0.0000          3rd Qu.:0.0000    
##  Max.   :1.0000   Max.   :1.0000          Max.   :1.0000    
##                                                             
##  producen_esterilidad producen_homosexualidad inyectan_el_virus
##  Min.   :0.00000      Min.   :0.00000         Min.   :0.0      
##  1st Qu.:0.00000      1st Qu.:0.00000         1st Qu.:0.0      
##  Median :0.00000      Median :0.00000         Median :1.0      
##  Mean   :0.08738      Mean   :0.01165         Mean   :0.6      
##  3rd Qu.:0.00000      3rd Qu.:0.00000         3rd Qu.:1.0      
##  Max.   :1.00000      Max.   :1.00000         Max.   :1.0      
##                                                                
##  antibioticos_son_buenos vitaminas_y_minerales   otros...85     
##  Min.   :0.0000          Min.   :0.000         Min.   :0.00000  
##  1st Qu.:0.0000          1st Qu.:0.000         1st Qu.:0.00000  
##  Median :0.0000          Median :0.000         Median :0.00000  
##  Mean   :0.4699          Mean   :0.435         Mean   :0.05243  
##  3rd Qu.:1.0000          3rd Qu.:1.000         3rd Qu.:0.00000  
##  Max.   :1.0000          Max.   :1.000         Max.   :1.00000  
##                                                                 
##  entrevistadoras
##  Min.   :1.000  
##  1st Qu.:1.000  
##  Median :2.000  
##  Mean   :1.736  
##  3rd Qu.:2.000  
##  Max.   :3.000  
## 

6 Una función más poderosa que summaryes skim pero requiere intalar el paquete skimr

7 install.packages(“skimr”)

if (!require(skimr)) {
  install.packages("skimr")
}
# Cargar la librería
library(skimr)
skim(datos)
Data summary
Name datos
Number of rows 515
Number of columns 86
_______________________
Column type frequency:
character 5
numeric 81
________________________
Group variables None

Variable type: character

skim_variable n_missing complete_rate min max empty n_unique whitespace
tipo_enfcro 0 1.00 5 23 0 6 0
Otras enfermedades cronicas, especifique 487 0.05 2 20 0 11 0
fuentes 0 1.00 5 116 0 30 0
mensajes_rec 0 1.00 14 117 0 22 0
mitos 0 1.00 5 773 0 155 0

Variable type: numeric

skim_variable n_missing complete_rate mean sd p0 p25 p50 p75 p100 hist
id 0 1 258.00 148.81 1 129.5 258 386.5 515 ▇▇▇▇▇
part_prev 0 1 0.09 0.29 0 0.0 0 0.0 1 ▇▁▁▁▁
municipio 0 1 4.85 2.07 1 3.5 6 6.0 7 ▃▁▁▁▇
edad 0 1 42.37 15.35 19 30.0 40 55.0 89 ▇▇▃▃▁
genero 0 1 0.43 0.50 0 0.0 0 1.0 1 ▇▁▁▁▆
nivel_edu 0 1 3.21 1.46 0 2.0 3 4.0 6 ▃▃▅▇▃
enf_cro 0 1 0.33 0.48 0 0.0 0 1.0 2 ▇▁▃▁▁
ninguna 0 1 0.68 0.47 0 0.0 1 1.0 1 ▃▁▁▁▇
hipertension 0 1 0.26 0.44 0 0.0 0 1.0 1 ▇▁▁▁▃
diabetes 0 1 0.12 0.32 0 0.0 0 0.0 1 ▇▁▁▁▁
epoc 0 1 0.01 0.09 0 0.0 0 0.0 1 ▇▁▁▁▁
renal 0 1 0.02 0.14 0 0.0 0 0.0 1 ▇▁▁▁▁
artritis 0 1 0.02 0.14 0 0.0 0 0.0 1 ▇▁▁▁▁
cardiopatia 0 1 0.00 0.04 0 0.0 0 0.0 1 ▇▁▁▁▁
hipotiroidismo 0 1 0.00 0.04 0 0.0 0 0.0 1 ▇▁▁▁▁
glaucoma 1 1 0.00 0.04 0 0.0 0 0.0 1 ▇▁▁▁▁
lupus 0 1 0.00 0.04 0 0.0 0 0.0 1 ▇▁▁▁▁
ulcera_venosa 0 1 0.00 0.04 0 0.0 0 0.0 1 ▇▁▁▁▁
area 0 1 0.64 0.48 0 0.0 1 1.0 1 ▅▁▁▁▇
hijxs 0 1 0.63 0.48 0 0.0 1 1.0 1 ▅▁▁▁▇
nucleo 0 1 5.67 43.87 1 3.0 4 5.0 999 ▇▁▁▁▁
empleo 0 1 1.02 0.76 0 1.0 1 1.0 3 ▂▇▁▁▁
ocupacion 0 1 3.77 3.11 0 1.0 3 6.0 10 ▇▆▁▂▃
ingreso 0 1 0.92 0.93 0 0.0 1 2.0 4 ▇▆▅▁▁
prev_per 0 1 0.47 0.69 0 0.0 0 1.0 3 ▇▃▁▁▁
rec_apoyo 0 1 29.43 162.24 0 1.0 3 3.0 999 ▇▁▁▁▁
satisfaccion 0 1 4.28 1.11 2 3.0 5 5.0 5 ▁▂▁▁▇
prev_fam 0 1 0.77 1.03 0 0.0 0 1.0 3 ▇▅▁▁▂
mortalidad 0 1 0.04 0.21 0 0.0 0 0.0 1 ▇▁▁▁▁
c1 0 1 1.07 0.34 1 1.0 1 1.0 3 ▇▁▁▁▁
c2 0 1 1.15 0.45 1 1.0 1 1.0 3 ▇▁▁▁▁
c3 0 1 1.64 0.79 1 1.0 1 2.0 3 ▇▁▃▁▃
c4 0 1 1.17 0.52 1 1.0 1 1.0 3 ▇▁▁▁▁
c5 0 1 2.16 0.88 1 1.0 2 3.0 3 ▆▁▃▁▇
c6 0 1 1.30 0.55 1 1.0 1 2.0 3 ▇▁▂▁▁
c7 0 1 1.94 0.95 1 1.0 2 3.0 3 ▇▁▂▁▇
c8 0 1 1.04 0.27 1 1.0 1 1.0 3 ▇▁▁▁▁
c9 0 1 1.09 0.35 1 1.0 1 1.0 3 ▇▁▁▁▁
c10 0 1 2.06 0.91 1 1.0 2 3.0 3 ▇▁▃▁▇
a1 0 1 3.99 0.81 2 3.0 4 5.0 5 ▁▅▁▇▆
a2 0 1 4.03 0.84 1 3.0 4 5.0 5 ▁▁▇▇▇
a3 0 1 2.25 0.95 1 1.0 2 3.0 5 ▆▇▇▂▁
a4 0 1 3.81 1.01 1 3.0 4 5.0 5 ▁▂▇▅▇
a5 0 1 2.75 0.88 1 2.0 3 3.0 5 ▂▂▇▂▁
p1 0 1 2.47 1.55 0 1.0 2 4.0 5 ▇▂▂▃▃
p2 0 1 1.58 1.39 0 0.5 1 3.0 5 ▇▂▂▁▁
p3 0 1 1.52 1.39 0 0.0 1 3.0 5 ▇▂▂▁▁
p4 0 1 2.94 1.69 0 1.0 3 5.0 5 ▇▂▃▃▇
p5 0 1 3.10 1.45 0 2.0 3 4.0 5 ▆▇▆▆▇
dosis 0 1 2.36 1.21 0 2.0 2 3.0 4 ▂▂▇▅▅
razon_nv 0 1 4.75 2.11 1 5.0 5 6.0 11 ▅▅▇▁▁
periodico 0 1 0.11 0.31 0 0.0 0 0.0 1 ▇▁▁▁▁
television 0 1 0.84 0.37 0 1.0 1 1.0 1 ▂▁▁▁▇
redes_sociales 0 1 0.76 0.43 0 1.0 1 1.0 1 ▂▁▁▁▇
personal_salud 0 1 0.12 0.33 0 0.0 0 0.0 1 ▇▁▁▁▁
radio 0 1 0.18 0.38 0 0.0 0 0.0 1 ▇▁▁▁▂
paginas_internet 0 1 0.22 0.42 0 0.0 0 0.0 1 ▇▁▁▁▂
escuela 0 1 0.00 0.04 0 0.0 0 0.0 1 ▇▁▁▁▁
mensajes 0 1 0.83 0.71 0 0.0 1 1.0 2 ▆▁▇▁▃
patrocinio 0 1 4.30 2.91 1 1.0 7 7.0 7 ▇▁▁▁▇
uso_de_mascarilla 0 1 0.41 0.49 0 0.0 0 1.0 1 ▇▁▁▁▆
distanciamiento_social 0 1 0.56 0.50 0 0.0 1 1.0 1 ▆▁▁▁▇
lavado_de_manos 0 1 0.62 0.49 0 0.0 1 1.0 1 ▅▁▁▁▇
ponerse_la_vacuna 0 1 0.26 0.44 0 0.0 0 1.0 1 ▇▁▁▁▃
no_recuerdo 0 1 0.01 0.10 0 0.0 0 0.0 1 ▇▁▁▁▁
todas 0 1 0.29 0.45 0 0.0 0 1.0 1 ▇▁▁▁▃
otros…71 0 1 0.01 0.09 0 0.0 0 0.0 1 ▇▁▁▁▁
No_he_escuchado 0 1 0.06 0.25 0 0.0 0 0.0 1 ▇▁▁▁▁
transmite_por_el_agua 0 1 0.72 0.45 0 0.0 1 1.0 1 ▃▁▁▁▇
transmite_en_las_suelas 0 1 0.85 0.35 0 1.0 1 1.0 1 ▂▁▁▁▇
rociar_desinfectantes 0 1 0.62 0.49 0 0.0 1 1.0 1 ▅▁▁▁▇
beben_alcohol 0 1 0.20 0.40 0 0.0 0 0.0 1 ▇▁▁▁▂
pueden_dejar_de_aplicar 0 1 0.14 0.34 0 0.0 0 0.0 1 ▇▁▁▁▁
no_se_debe_vacunar 0 1 0.15 0.36 0 0.0 0 0.0 1 ▇▁▁▁▂
producen_esterilidad 0 1 0.09 0.28 0 0.0 0 0.0 1 ▇▁▁▁▁
producen_homosexualidad 0 1 0.01 0.11 0 0.0 0 0.0 1 ▇▁▁▁▁
inyectan_el_virus 0 1 0.60 0.49 0 0.0 1 1.0 1 ▅▁▁▁▇
antibioticos_son_buenos 0 1 0.47 0.50 0 0.0 0 1.0 1 ▇▁▁▁▇
vitaminas_y_minerales 0 1 0.43 0.50 0 0.0 0 1.0 1 ▇▁▁▁▆
otros…85 0 1 0.05 0.22 0 0.0 0 0.0 1 ▇▁▁▁▁
entrevistadoras 0 1 1.74 0.77 1 1.0 2 2.0 3 ▇▁▆▁▃

8 Transformación de Datos con dplyr

El paquete dplyr es una herramienta poderosa y esencial en el ecosistema de R para la transformación de datos. Proporciona una “gramática” de verbos intuitiva que simplifica las tareas más comunes de gestión y resumen de datos.

Algunos de los “verbos” principales que exploraremos son:

  • select(): para seleccionar columnas.
  • filter(): para filtrar filas según condiciones.
  • mutate(): para crear o modificar columnas.
  • arrange(): para ordenar filas.
  • group_by() y summarise(): para agrupar y resumir datos.

El uso de dplyr no solo hace el código más legible, sino también más eficiente.

8.1 Instalar y cargar dplyr

Antes de poder usar sus funciones, necesitamos asegurarnos de que el paquete dplyr esté instalado en nuestro sistema y cargado en nuestra sesión de R.

El siguiente bloque de código verifica si dplyr está instalado. Si no lo está, lo instalará desde CRAN. Luego, cargará el paquete para que podamos usar sus funciones.

# Instalar si no está presente
if (!require(dplyr)) {
  install.packages("dplyr")
}
# Cargar la librería
library(dplyr)

8.2 Eliminación del contenido de una base de datos

Si necesitamos eliminar solo una celda, debemos asignar “NA” a la variable cuya ubicación está indexada, como se muestra a continuación.

# Eliminamos en la fila 355 de la columna "edad" el valor erróneo (5 años)
datos$edad[355] = NA 

8.3 Reemplazar Valores Específicos (Corrección de Datos)

Durante la limpieza de datos, es común encontrar y corregir errores de entrada. Por ejemplo, un valor que es claramente incorrecto, como una edad de “5” en un estudio de adultos, por eso lo eliminamos y le colocamos el valor “NA” en el código anterior.

Supongamos que encontramos el dato verdadero de la edad de la observacoón 355 (fila 355), podemos ahora introducir el valor verdadero con el siguiente código:

# Corregimos el error en la fila 355 de la columna "edad"
datos$edad[355] <- 52

8.4 Seleccionar columnas con select()

A menudo, nuestros conjuntos de datos contienen más columnas de las que necesitamos para un análisis específico. El verbo select() nos permite crear un nuevo data.frame que contiene solo un subconjunto de las columnas originales.

La sintaxis es simple: select(data, columna1, columna2, ...).

# Creamos un nuevo data frame llamado 'datos_personales'
# que solo contiene las columnas id, genero y edad
datos_personales <- select(datos, id, genero, edad)

También puedes usar select() para excluir columnas, lo cual es muy útil cuando quieres quitar solo unas pocas. Para ello, simplemente pones un signo de menos (-) delante de los nombres de las columnas que quieres eliminar.

# Obtenemos los nombres de las variables de la base "datos"
names(datos)
##  [1] "id"                                      
##  [2] "part_prev"                               
##  [3] "municipio"                               
##  [4] "edad"                                    
##  [5] "genero"                                  
##  [6] "nivel_edu"                               
##  [7] "enf_cro"                                 
##  [8] "tipo_enfcro"                             
##  [9] "ninguna"                                 
## [10] "hipertension"                            
## [11] "diabetes"                                
## [12] "epoc"                                    
## [13] "renal"                                   
## [14] "artritis"                                
## [15] "cardiopatia"                             
## [16] "hipotiroidismo"                          
## [17] "glaucoma"                                
## [18] "lupus"                                   
## [19] "ulcera_venosa"                           
## [20] "Otras enfermedades cronicas, especifique"
## [21] "area"                                    
## [22] "hijxs"                                   
## [23] "nucleo"                                  
## [24] "empleo"                                  
## [25] "ocupacion"                               
## [26] "ingreso"                                 
## [27] "prev_per"                                
## [28] "rec_apoyo"                               
## [29] "satisfaccion"                            
## [30] "prev_fam"                                
## [31] "mortalidad"                              
## [32] "c1"                                      
## [33] "c2"                                      
## [34] "c3"                                      
## [35] "c4"                                      
## [36] "c5"                                      
## [37] "c6"                                      
## [38] "c7"                                      
## [39] "c8"                                      
## [40] "c9"                                      
## [41] "c10"                                     
## [42] "a1"                                      
## [43] "a2"                                      
## [44] "a3"                                      
## [45] "a4"                                      
## [46] "a5"                                      
## [47] "p1"                                      
## [48] "p2"                                      
## [49] "p3"                                      
## [50] "p4"                                      
## [51] "p5"                                      
## [52] "dosis"                                   
## [53] "razon_nv"                                
## [54] "fuentes"                                 
## [55] "periodico"                               
## [56] "television"                              
## [57] "redes_sociales"                          
## [58] "personal_salud"                          
## [59] "radio"                                   
## [60] "paginas_internet"                        
## [61] "escuela"                                 
## [62] "mensajes"                                
## [63] "patrocinio"                              
## [64] "mensajes_rec"                            
## [65] "uso_de_mascarilla"                       
## [66] "distanciamiento_social"                  
## [67] "lavado_de_manos"                         
## [68] "ponerse_la_vacuna"                       
## [69] "no_recuerdo"                             
## [70] "todas"                                   
## [71] "otros...71"                              
## [72] "No_he_escuchado"                         
## [73] "mitos"                                   
## [74] "transmite_por_el_agua"                   
## [75] "transmite_en_las_suelas"                 
## [76] "rociar_desinfectantes"                   
## [77] "beben_alcohol"                           
## [78] "pueden_dejar_de_aplicar"                 
## [79] "no_se_debe_vacunar"                      
## [80] "producen_esterilidad"                    
## [81] "producen_homosexualidad"                 
## [82] "inyectan_el_virus"                       
## [83] "antibioticos_son_buenos"                 
## [84] "vitaminas_y_minerales"                   
## [85] "otros...85"                              
## [86] "entrevistadoras"
# identificamos algunas variables que no vamos a utilizar como las variables: otras enfermedades crónicas, mitos, fuentes y otros...71.
datos <- select(datos, -"tipo_enfcro", -"Otras enfermedades cronicas, especifique", -"otros...71", -"fuentes", -"mitos", -"mensajes_rec", -"otros...71", -"otros...85")

8.5 Filtrar filas con filter()

La función filter() es una de las herramientas más útiles para el análisis exploratorio, ya que nos permite crear un subconjunto de nuestros datos que cumple con condiciones lógicas específicas. Podemos filtrar basándonos en valores de una o más columnas.

La sintaxis es: filter(data, condicion1, condicion2, ...). Por defecto, múltiples condiciones se unen con un “Y” lógico (&).

# Ejemplo 1: Filtrar para obtener solo a los participantes de género "Femenino"
participantes_femenino <- filter(datos, genero == 0)

Podemos combinar múltiples condiciones para hacer filtros más complejos. Usemos & para “Y” y | para “O”.

# Ejemplo 2: Filtrar para obtener participantes mayores de 60 años 
# Y que tengan esquema incompleto de la vacuna contra la COVID-19
adult_mayores_esquema_incomp <- filter(datos, edad > 60 & dosis < 3)

8.6 Crear o modificar columnas con mutate()

El verbo mutate() es fundamental para la ingeniería de características (feature engineering), ya que nos permite añadir nuevas columnas que son el resultado de cálculos sobre las columnas existentes.

En este ejemplo, crearemos una nueva variable llamada puntaje_A, que será el promedio de las respuestas a las 5 preguntas de actitud (de a1 a a5) para cada participante.

# Creamos un nuevo data frame con la columna 'puntaje_A'
datos <- mutate(datos, puntaje_A = (a1 + a2 + a3 + a4 + a5))
mean(datos$puntaje_A)
## [1] 16.82718
# Para verificar, mostramos solo las columnas relevantes del resultado
# Usamos select() para facilitar la visualización
knitr::kable(
  head(select(datos, id, a1:a5, puntaje_A)), 
  caption = "Data frame con el nuevo puntaje de actitud"
)
Data frame con el nuevo puntaje de actitud
id a1 a2 a3 a4 a5 puntaje_A
1 5 5 1 5 1 17
2 4 5 2 5 3 19
3 5 5 5 5 5 25
4 5 5 5 5 1 21
5 4 4 3 4 4 19
6 3 3 1 5 4 16

mutate() es increíblemente flexible. Puedes realizar desde operaciones aritméticas simples, como en este caso, hasta transformaciones mucho más complejas usando cualquier función de R.

8.7 Ordenar filas con arrange()

El verbo arrange() nos permite reordenar las filas de nuestro data.frame basándonos en los valores de una o más columnas. Esto es muy útil para identificar a los participantes con los puntajes más altos o más bajos en una variable de interés.

Por defecto, arrange() ordena en forma ascendente (de menor a mayor). Para ordenar en forma descendente, envolvemos el nombre de la columna en la función desc().

# Ordenamos a los participantes por su puntaje de actitud, de mayor a menor.
datos <- arrange(datos, desc(puntaje_A))

# Mostramos las primeras filas del resultado para verificar el ordenamiento.
# Seleccionamos columnas clave para que la tabla sea más fácil de leer.
knitr::kable(
  head(select(datos, id, genero, edad, puntaje_A)), 
  caption = "Participantes ordenados por el puntaje de actitud más alto."
)
Participantes ordenados por el puntaje de actitud más alto.
id genero edad puntaje_A
3 0 27 25
75 1 30 25
14 1 20 23
69 0 31 23
72 0 35 23
83 1 34 23

9 Volvemosa ordenar según el orden correlativo (id)

datos <- arrange(datos, id)

9.1 Recodificar Múltiples Variables con across()

Una tarea muy frecuente en la preparación de datos es la recodificación, donde cambiamos los valores de una variable según ciertas reglas. Cuando necesitamos aplicar la misma regla a muchas variables, escribir el código para cada una sería tedioso y propenso a errores.

La función across() de dplyr es la solución perfecta para esto. Nos permite aplicar la misma operación (en este caso, una recodificación) a un conjunto de columnas al mismo tiempo.

# Recodificar todas las variables de `c1` a `c10` que ya existen en nuestra base de datos. La regla es: si el valor es `1`, se mantiene como `1`; si es `2` o `3`, se convierte en `0`. Las nuevas variables se llamarán `c1recod`, `c2recod`, etc.
datos <- datos %>%
  mutate(
    across(
      .cols = c1:c10,
      .fns = ~ ifelse(.x == 1, 1, 0),
      .names = "{.col}recod"
    )
  )

# Para verificar, mostramos las primeras 5 columnas originales y sus 5 correspondientes recodificadas
knitr::kable(
  head(select(datos, c1:c5, c1recod:c5recod)),
  caption = "Variables originales y sus correspondientes recodificaciones."
)
Variables originales y sus correspondientes recodificaciones.
c1 c2 c3 c4 c5 c1recod c2recod c3recod c4recod c5recod
3 2 3 1 1 0 0 0 1 1
1 1 1 1 3 1 1 1 1 0
1 1 3 1 1 1 1 0 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 3 1 1 1 1 0
1 1 3 1 1 1 1 0 1 1

Analicemos el código:

  • across(.cols = c1:c10, ...): Le decimos a mutate que aplique una operación a todas las columnas desde c1 hasta c10.

  • .fns = ~ ifelse(.x == 1, 1, 0): Esta es la función que se aplica a cada columna. ~ crea una función anónima, .x es un marcador de posición para la columna que se está procesando en ese momento, y ifelse() aplica nuestra regla lógica.

  • .names = "{.col}recod": Aquí definimos cómo se llamarán las nuevas columnas. {.col} toma el nombre de la columna original y le añade el sufijo “recod”.

9.2 Crear una Variable de Puntuación a partir de Múltiples Columnas

Después de recodificar nuestras variables, un paso lógico es combinarlas en un único puntaje o índice. En este caso, crearemos la variable puntaje_C calculando el promedio de todas las variables recodificadas (c1recod a c10recod).

Para hacer esto de manera eficiente, usaremos mutate() junto con la función rowMeans(), que calcula la media para cada fila a través de un conjunto de columnas que le especifiquemos.

# Agregamos la variable puntaje_C sobreescribiendo la misma base de datos

datos <- datos %>%
  mutate(
    # La función rowSums() necesita un data frame como input,
    # por eso seleccionamos las columnas de interés con select() justo dentro.
    puntaje_C = rowSums(select(., c1recod:c10recod))
  )

# Para verificar, mostramos el ID del participante, las variables recodificadas y el nuevo puntaje promedio.
knitr::kable(
  head(select(datos, id, c1recod:c10recod, puntaje_C)),
  caption = "Data frame final con el puntaje promedio de conocimiento",
  digits = 2 # Redondeamos los decimales para una mejor lectura
)
Data frame final con el puntaje promedio de conocimiento
id c1recod c2recod c3recod c4recod c5recod c6recod c7recod c8recod c9recod c10recod puntaje_C
1 0 0 0 1 1 1 0 1 1 0 5
2 1 1 1 1 0 1 0 1 1 1 8
3 1 1 0 1 1 0 0 1 0 1 6
4 1 1 1 1 1 1 0 1 1 0 8
5 1 1 1 1 0 1 0 1 1 1 8
6 1 1 0 1 1 0 1 1 1 1 8

Como puedes ver, hemos creado exitosamente una nueva variable puntaje_C que resume la información de 10 columnas en un solo indicador numérico, completando así nuestro proceso de manipulación de datos. Sin embargo, los datos están ordenados según el puntaje de actitudes. Debemos reordenar según el id:

Esta es una forma avanzada de crear una variable con la que pudimos creamos la variable puntaje_A. Creemos la misma variable puntaje_A, sobre-escribiendo la que ya habíamos creado.

# Agregamos la variable puntaje_A sustituyendo la que ya había sido creada en la misma base de datos

datos <- datos %>%
  mutate(
    # La función rowSums() necesita un data frame como input,
    # por eso seleccionamos las columnas de interés con select() justo dentro.
    puntaje_A = rowSums(select(., a1:a5))
  )

# Para verificar, mostramos el ID del participante, las variables recodificadas y el nuevo puntaje promedio.
knitr::kable(
  head(select(datos, id, a1:a5, puntaje_A)),
  caption = "Data frame final con el puntaje promedio de actitudes.",
  digits = 2 # Redondeamos los decimales para una mejor lectura
)
Data frame final con el puntaje promedio de actitudes.
id a1 a2 a3 a4 a5 puntaje_A
1 5 5 1 5 1 17
2 4 5 2 5 3 19
3 5 5 5 5 5 25
4 5 5 5 5 1 21
5 4 4 3 4 4 19
6 3 3 1 5 4 16

Y por último la variable puntaje_P

# Agregamos la variable puntaje_P sobreescribiendo la misma base de datos

datos <- datos %>%
  mutate(
    # La función rowSums() necesita un data frame como input,
    # por eso seleccionamos las columnas de interés con select() justo dentro.
    puntaje_P = rowSums(select(., p1:p5))
  )

# Para verificar, mostramos el ID del participante, las variables recodificadas y el nuevo puntaje promedio.
knitr::kable(
  head(select(datos, id, a1:a5, puntaje_P)),
  caption = "Data frame final con el puntaje promedio de prácticas",
  digits = 2 # Redondeamos los decimales para una mejor lectura
)
Data frame final con el puntaje promedio de prácticas
id a1 a2 a3 a4 a5 puntaje_P
1 5 5 1 5 1 20
2 4 5 2 5 3 5
3 5 5 5 5 5 18
4 5 5 5 5 1 16
5 4 4 3 4 4 5
6 3 3 1 5 4 15

9.2.1 Convertir una Variable a Factor

En R, las variables categóricas (como “genero”) a menudo se cargan como texto o caracteres (character). Sin embargo, para muchos análisis estadísticos y gráficos (por ejemplo, con ggplot2), es mejor convertirlas a un tipo de dato especial llamado factor.

Un factor le dice a R que una variable, aunque contenga texto, representa categorías discretas. Esto también nos permite definir un orden específico para esas categorías si es necesario.

Primero, verifiquemos el tipo de dato actual de la columna genero.

# Vemos que la clase es 'character'
class(datos$genero)
## [1] "numeric"
# Convertir en factor
datos$genero <- factor(datos$genero)

9.2.2 Etiquetar los Niveles de un Factor

A menudo, las bases de datos codifican las variables categóricas con números (por ejemplo, 0 = Femenino, 1 = Masculino). Si bien esto es eficiente para el almacenamiento, no es ideal para la interpretación de resultados. El siguiente paso es asignar etiquetas de texto a estos números.

Vamos a convertir nuestra variable numérica genero en un factor con las etiquetas correspondientes y actualizaremos nuestro data.frame principal.

# Usamos mutate() para modificar la columna 'genero'
datos <- datos %>%
  mutate(
    genero = factor(genero,
                    levels = c(0, 1),
                    labels = c("Femenino", "Masculino"))
  )

# Verificamos la estructura de la variable para confirmar el cambio.
# Ahora debería ser de tipo 'Factor' con dos niveles etiquetados.
str(datos$genero)
##  Factor w/ 2 levels "Femenino","Masculino": 1 2 1 2 1 2 1 1 2 2 ...

Para una verificación final, podemos crear una tabla de frecuencias para ver cuántos participantes hay en cada una de las nuevas categorías etiquetadas.

knitr::kable(
  table(datos$genero),
  col.names = c("Genero", "Frecuencia"),
  caption = "Tabla de Frecuencias para la Variable 'genero' Etiquetada."
)
Tabla de Frecuencias para la Variable ‘genero’ Etiquetada.
Genero Frecuencia
Femenino 291
Masculino 224

Vamos a recodificar la variable mensajes para que tenga dos niveles: “Sí” (para el valor 1) y “No” (para todos los demás valores) y agregarla a nuestra base de datos con el nombre “mensajes_recod”.

# 1. Recodificar la variable "mensajes"
#    - Usamos ifelse() para convertir 1 a 1 y cualquier otro valor (0, 2) a 0.
#    - Usamos factor() para convertir la nueva variable numérica en un factor
#      y asignarle las etiquetas "No" y "Sí" a los niveles 0 y 1.
datos <- datos %>%
  mutate(
    mensajes_recod = factor(
      ifelse(mensajes == 1, 1, 0),
      levels = c(0, 1),
      labels = c("No", "Sí")
    )
  )

# Guardar la Base de Datos modificada

Después de todo el trabajo de limpieza, recodificación y creación de nuevas variables, es una buena práctica guardar el data.frame final en un nuevo archivo. Esto preserva tu trabajo y te permite usar la base de datos limpia en futuros análisis sin tener que repetir todos los pasos.

Para escribir en formato .xlsx, usaremos el paquete writexl, que es muy ligero y eficiente.

9.3 Instalar y cargar writexl

# Instalar si no está presente
if (!require(writexl)) {
  install.packages("writexl")
}
# Cargar la librería
library(writexl)

9.4 Escribir el data frame a un archivo de Excel

Ahora, usaremos la función write_xlsx(). Esta función toma dos argumentos principales: el data.frame que quieres guardar y el nombre que le quieres dar al nuevo archivo.

# Asumimos que 'datos' es el data frame que contiene todos los cambios que hemos hecho a lo largo del tutorial.
write_xlsx(datos, "CAP_modif.xlsx")

¡Y eso es todo! Después de ejecutar este código, verás tu archivo de Excel llamado CAP.xlsx en la carpeta de tu proyecto de RStudio ha sufrido todas las modificaciones.

10 Ahora te toca a tí!

Convierte en factor y etiqueta todas las variables categóricas de acuerdo con tu libro de códigos Esto es indispensable para diseñar los gráficos que es el tema del Tutorial 3