Ejercicio: Importar y Visualizar Datos de la Encuesta CEP

Lo primero que tienes que hacer es descargar la base de datos CEP de este link y abrir la base en formato spss, excel y csv. Como la base ya viene en spss, tendrás que transformarlo en archivo excel y csv.

El ejercicio consiste en abrir bases de datos en R. El siguiente paso será mostrar cuáles son las variables que tiene la base de datos y a que clase pertenencen.

Y por último mostrar alguna variable que encuentres interesante de visualizar mediante ggplot (geom_point, geom_bar (fill,stack y dodge),geom_errorbar (que muestra los intervalos de confianza), pueden mostrarlo mediante un gráfico o mediante distintas formas de visualizar el mismo dato. Ver si existen variables banner para realizar gráficos cruce y graficarlos.

1. Importación de los Datos

Luego de descargar el archivo encuesta_cep84_dic2019.zip en la carpeta raw de tu proyecto, puedes descomprimir el archivo en la misma carpeta. Tu directorio raw debiese verse algo así:

library(here)
dir(here("raw"))
## [1] "encuesta_cep84_dic2019"     "encuesta_cep84_dic2019.zip"
dir(here("raw", "encuesta_cep84_dic2019"))
## [1] "Encuesta CEP 84 Dic 2019 v1.sav"          
## [2] "Manual del Usuario Encuesta CEP 84 v2.pdf"

Puedes ver que el archivo viene en el formato que utiliza el software spss, es decir que tiene extensión .sav. Para importar este tipo de archivos utilizarás el paquete {haven} y para manipular la base de datos, el paquete {dplyr}. Intenta hacer lo mismo con excel y csv. Una función para leer desde excel es read_xlsx() del paquete {readxl} y para leer un csv puedes usar read_csv() del paquete {readr}.

library(haven)
library(dplyr)

datos_cep <- here("raw", "encuesta_cep84_dic2019", "Encuesta CEP 84 Dic 2019 v1.sav") # Dirección del archivo
datos_cep <- datos_cep %>% read_sav()                                                 # Leer el archivo

Listo! Ya puedes comenzar a explorar la base de datos. Primero veamos cuántas filas y cuántas columnas tiene el data.frame usando nrow y ncol. Podrás ver que son bastantes variables (columnas) por lo que talvez usar str o summary no sea muy útil.

library(magrittr)

datos_cep %>% nrow()                                                                  # ¿Cuántas filas tiene?
## [1] 1496
datos_cep %>% ncol()                                                                  # ¿Cuántas variables tiene?
## [1] 258
datos_cep %>% names %>% head(60)                                                      # ¿Cómo se llaman?
##  [1] "ZONA"         "PROVINCIA_BD" "COMUNA_BD"    "UMP"         
##  [5] "FECHAFIN"     "REGION"       "SV_1"         "SV_2"        
##  [9] "SV3_1"        "SV3_2"        "SV3_3"        "SV3_4"       
## [13] "SV3_5"        "SV3_6"        "SV_4"         "MB_P1_1"     
## [17] "MB_P1_2"      "MB_P1_3"      "MB_P2"        "MB_P3"       
## [21] "MB_P4"        "MB_P5"        "MB_P6"        "MB_P7"       
## [25] "MB_P8"        "MB_P8A"       "MB_P9"        "MB_P9A"      
## [29] "MB_P10_A"     "MB_P10_B"     "MB_P10_C"     "MB_P10_D"    
## [33] "MB_P10_E"     "MB_P10_F"     "MB_P10_G"     "MB_P10_H"    
## [37] "MB_P10_I"     "MB_P10_J"     "MB_P10_K"     "MB_P10_L"    
## [41] "MB_P10_M"     "MB_P10_N"     "MB_P10_O"     "MB_P10_P"    
## [45] "MB_P10_Q"     "MB_P10_R"     "MB_P10_S"     "MB_P10_T"    
## [49] "MB_P10_U"     "MB_P10_V"     "MB_P10_W"     "MB_P10_X"    
## [53] "MB_P10_Y"     "MB_P10_Z"     "MB_P10_AA"    "MB_P10_BB"   
## [57] "MB_P10_CC"    "MB_P10_DD"    "MB_P11_1"     "MB_P11_2"
datos_cep %>% use_series(SV_1) %>% class                                              # ¿Qué clase la variable?                     
## [1] "haven_labelled"
datos_cep %>% use_series(SV_1) %>% typeof                                             # ¿Qué tipo de dato es?                     
## [1] "double"
datos_cep %>% use_series(SV_1) %>% attributes                                         # ¿Qué atributos tiene?                     
## $label
## [1] "SV1. ¿Cuán satisfecho está usted con su vida en este momento?"
## 
## $format.spss
## [1] "F2.0"
## 
## $display_width
## [1] 6
## 
## $class
## [1] "haven_labelled"
## 
## $labels
## 1.- Totalmente insatisfecho                           2 
##                           1                           2 
##                           3                           4 
##                           3                           4 
##                           5                           6 
##                           5                           6 
##                           7                           8 
##                           7                           8 
##                           9  10.- Totalmente satisfecho 
##                           9                          10 
##               88. - No sabe           99. - No contesta 
##                          88                          99
datos_cep %>% use_series(SV_1) %>% attr("label")                                      # ¿Cuál es la pregunta?                     
## [1] "SV1. ¿Cuán satisfecho está usted con su vida en este momento?"
datos_cep %>% use_series(SV_1) %>% attr("labels")                                     # ¿Cuál es la respuesta?                     
## 1.- Totalmente insatisfecho                           2 
##                           1                           2 
##                           3                           4 
##                           3                           4 
##                           5                           6 
##                           5                           6 
##                           7                           8 
##                           7                           8 
##                           9  10.- Totalmente satisfecho 
##                           9                          10 
##               88. - No sabe           99. - No contesta 
##                          88                          99
datos_cep                                                                             # Ver las 10 primeras filas
## # A tibble: 1,496 x 258
##       ZONA PROVINCIA_BD COMUNA_BD       UMP FECHAFIN  REGION  SV_1  SV_2
##    <dbl+l> <chr>        <chr>     <dbl+lbl> <chr>    <dbl+l> <dbl> <dbl>
##  1 2 [Rur~ 83           8301      254 [254] 01-12-2~  8 [8]  7 [7] 3 [3]
##  2 2 [Rur~ 71           7109      250 [250] 11-12-2~  7 [7]  4 [4] 5 [5]
##  3 1 [Urb~ 131          13101     109 [109] 15-12-2~ 13 [13] 8 [8] 4 [4]
##  4 1 [Urb~ 73           7301       62 [62]  09-12-2~  7 [7]  7 [7] 4 [4]
##  5 1 [Urb~ 131          13132     208 [208] 13-12-2~ 13 [13] 7 [7] 3 [3]
##  6 1 [Urb~ 131          13106     130 [130] 14-12-2~ 13 [13] 7 [7] 4 [4]
##  7 1 [Urb~ 73           7301       62 [62]  09-12-2~  7 [7]  7 [7] 5 [5]
##  8 1 [Urb~ 131          13106     130 [130] 14-12-2~ 13 [13] 6 [6] 4 [4]
##  9 1 [Urb~ 131          13106     130 [130] 15-12-2~ 13 [13] 6 [6] 4 [4]
## 10 1 [Urb~ 131          13106     130 [130] 15-12-2~ 13 [13] 7 [7] 4 [4]
## # ... with 1,486 more rows, and 250 more variables: SV3_1 <dbl+lbl>,
## #   SV3_2 <dbl+lbl>, SV3_3 <dbl+lbl>, SV3_4 <dbl+lbl>, SV3_5 <dbl+lbl>,
## #   SV3_6 <dbl+lbl>, SV_4 <dbl+lbl>, MB_P1_1 <dbl+lbl>, MB_P1_2 <dbl+lbl>,
## #   MB_P1_3 <dbl+lbl>, MB_P2 <dbl+lbl>, MB_P3 <dbl+lbl>, MB_P4 <dbl+lbl>,
## #   MB_P5 <dbl+lbl>, MB_P6 <dbl+lbl>, MB_P7 <dbl+lbl>, MB_P8 <dbl+lbl>,
## #   MB_P8A <dbl+lbl>, MB_P9 <dbl+lbl>, MB_P9A <dbl+lbl>,
## #   MB_P10_A <dbl+lbl>, MB_P10_B <dbl+lbl>, MB_P10_C <dbl+lbl>,
## #   MB_P10_D <dbl+lbl>, MB_P10_E <dbl+lbl>, MB_P10_F <dbl+lbl>,
## #   MB_P10_G <dbl+lbl>, MB_P10_H <dbl+lbl>, MB_P10_I <dbl+lbl>,
## #   MB_P10_J <dbl+lbl>, MB_P10_K <dbl+lbl>, MB_P10_L <dbl+lbl>,
## #   MB_P10_M <dbl+lbl>, MB_P10_N <dbl+lbl>, MB_P10_O <dbl+lbl>,
## #   MB_P10_P <dbl+lbl>, MB_P10_Q <dbl+lbl>, MB_P10_R <dbl+lbl>,
## #   MB_P10_S <dbl+lbl>, MB_P10_T <dbl+lbl>, MB_P10_U <dbl+lbl>,
## #   MB_P10_V <dbl+lbl>, MB_P10_W <dbl+lbl>, MB_P10_X <dbl+lbl>,
## #   MB_P10_Y <dbl+lbl>, MB_P10_Z <dbl+lbl>, MB_P10_AA <dbl+lbl>,
## #   MB_P10_BB <dbl+lbl>, MB_P10_CC <dbl+lbl>, MB_P10_DD <dbl+lbl>,
## #   MB_P11_1 <dbl+lbl>, MB_P11_2 <dbl+lbl>, MB_P11_3 <dbl+lbl>,
## #   MB_P11_4 <dbl+lbl>, MB_P11_5 <dbl+lbl>, MB_P11_6 <dbl+lbl>,
## #   MB_P11_7 <dbl+lbl>, MB_P11_8 <dbl+lbl>, MB_P11_9 <dbl+lbl>,
## #   MB_P11_10 <dbl+lbl>, MB_P11_11 <dbl+lbl>, MB_P11_12 <dbl+lbl>,
## #   MB_P11_13 <dbl+lbl>, MB_P11_14 <dbl+lbl>, MB_P11_15 <dbl+lbl>,
## #   MB_P11_16 <dbl+lbl>, MB_P11_17 <dbl+lbl>, MB_P12_1 <dbl+lbl>,
## #   MB_P12_2 <dbl+lbl>, MB_P13_1 <dbl+lbl>, MB_P13_2 <dbl+lbl>,
## #   MB_P13_3 <dbl+lbl>, MB_P13_4 <dbl+lbl>, MB_P13_5 <dbl+lbl>,
## #   MB_P13_6 <dbl+lbl>, MB_P13_7 <dbl+lbl>, MB_P14 <dbl+lbl>,
## #   ESP_1 <dbl+lbl>, ESP_2 <dbl+lbl>, ESP_3 <dbl+lbl>, ESP_4 <dbl+lbl>,
## #   ESP_5_1 <dbl+lbl>, ESP_5_2 <dbl+lbl>, ESP_5_3 <dbl+lbl>,
## #   ESP_5_4 <dbl+lbl>, ESP_6_1 <dbl+lbl>, ESP_6_2 <dbl+lbl>,
## #   ESP_7 <dbl+lbl>, ESP_8_1 <dbl+lbl>, ESP_8_2 <dbl+lbl>,
## #   ESP_8_3 <dbl+lbl>, ESP_8_4 <dbl+lbl>, ESP_8_5 <dbl+lbl>,
## #   ESP_8_6 <dbl+lbl>, ESP_8_7 <dbl+lbl>, ESP_8_8 <dbl+lbl>,
## #   ESP_9_1 <dbl+lbl>, ESP_9_2 <dbl+lbl>, ESP_10_1 <dbl+lbl>,
## #   ESP_10_2 <dbl+lbl>, ...

2. Visualización de los Datos: Gráficos de Barras

Como ejemplo usaré la pregunta sobre “Satisfacción con la vida” (SV_1), con esta variable mostraré distintas visualizaciones. Tu puedes usar la misma variable si así lo deseas, pero te recomiendo fuertemente que intentes con una variable distina.

Según el Manual de Usuario de la Encuesta CEP, el fraseo de la pregunta es el siguiente:

Considerando todas las cosas, ¿cuán satisfecho está usted con su vida en este momento? Por favor use esta tarjeta en que 1 significa que usted está “totalmente insatisfecho” y 10 significa que usted está “totalmente satisfecho”. ¿Dónde se ubicaría usted?

Las respuesta van del 1 al 10, donde 1 es “Totalmente insatisfecho” y 10, “Totalmente satisfecho”. Adicionalmente están las opciones 88 “No sabe” y 99 “No contesta”.

Debido a que es una de las visualizaciones que más utilizamos, comenzaré explicando cómo generar gráficos de barra y sus distintos componentes, particularmente las variables estéticas y las posiciones.

2.1 Gráficos de Barra: Definiendo las variables estéticas

2.1.1 La variable estética x

La definición mínima necesaria para poder generar un gráfico de barras es la variable x, que corresponde al eje horizontal. Una vez definiendo esta variable estética podemos realizar un gráfico de barra usando la geometría geom_bar(). La altura de cada barra (la variable y) corresponde al número de casos para cada valor de x, esta se calcula de forma automática. Algo parecido se logra con la geometría geom_histogram() pero con la diferencia de que el histograma funciona solo cuando la variable x es continua, mientras que geom_bar() funciona tanto con variables continuas y como discretas.

Para este ejemplo utilizamos la función as.factor para transformar los valores de la variable “Satisfacción de la Vida” (SV_1) a variable categórica. Intenta ver que sucede si omites esta función. ¿Qué diferencias puedes notar? Intenta también usando geom_histogram()

library(ggplot2)

gg_sv1_bar <- datos_cep  %>% ggplot() 
gg_sv1_bar <- gg_sv1_bar %+% aes(x = SV_1 %>% as.factor)
gg_sv1_bar <- gg_sv1_bar %+% geom_bar()
gg_sv1_bar <- gg_sv1_bar %+% labs(title = "Satisfacción con la Vida")
gg_sv1_bar <- gg_sv1_bar %+% labs(subtitle = "geom_bar()")
gg_sv1_bar <- gg_sv1_bar %+% labs(x = "nivel de satisfacción")
gg_sv1_bar <- gg_sv1_bar %+% labs(y = "frecuencia")
gg_sv1_bar

2.1.2 La variable estética y

Hasta el momento hemos logrado visualizar la frecuencia de cada respuesta, sin embargo la función detrás del conteo solo considera el número de casos para cada valor de x. Cuando trabajamos con bases ponderadas esta opción no nos sirve ya que necesitamos realizar un conteo tomando en cuenta los ponderadores. La solución es generar el conteo ponderado antes de llamar a la función ggplot(). Para esto necesitamos llamar a la función count(), esta función realiza el conteo del número de casos para cada valor de la variable que queramos (en nuestro caso SV_1) y además da la opción de agregar los ponderadores usando el argumento wt. Intenta ver que sucede si omites este argumento. ¿Qué diferencias puedes notar?

datos_cep %>% 
  count(SV_1, wt = PONDERADOR) 
## # A tibble: 11 x 2
##                                SV_1      n
##  *                        <dbl+lbl>  <dbl>
##  1  1 [1.- Totalmente insatisfecho]  22.7 
##  2  2 [2]                            17.6 
##  3  3 [3]                            29.7 
##  4  4 [4]                           100.  
##  5  5 [5]                           220.  
##  6  6 [6]                           199.  
##  7  7 [7]                           286.  
##  8  8 [8]                           214.  
##  9  9 [9]                           152.  
## 10 10 [10.- Totalmente satisfecho]  252.  
## 11 88 [88. - No sabe]                 2.65

El resultado de la función count es una nueva base que tiene tantas filas como valores tiene la variable SV_1 y dos columnas: la primera con el valor de SV_1 y la segunda con el valor del conteo (el nombre es n por defecto, pero se puede asignar otro nombre especificando el argumento name de la siguiente manera count(SV_1, wt = PONDERADOR, name = "conteo_ponderado")). Inténtalo

Ahora tenemos dos variables, SV_1 que será nuestra variable x y n que será nuestra variable y (la que determinará el alto de las barras) para poder generar la visualizavión necesitaremos la función geom_col().

La diferencia entre geom_bar() y geom_col(), es que geom_bar() solo requiere la variable x, la variable y es calcualda de forma automática, mientras que geom_col() requiere que se definan ambas variables x e y.

A continuación podrás ver el nuevo gráfico considerando el ponderador, ¿Puedes notar la diferencia con el gráfico anterior? Intenta omitiendo el argumento wt en la función count ¿Que observas al comparar ambos gráficos?

datos_sv1_wt <- datos_cep    %>% count(SV_1, wt = PONDERADOR) 
gg_sv1_col_1 <- datos_sv1_wt %>% ggplot() 
gg_sv1_col_1 <- gg_sv1_col_1 %+% aes(x = SV_1 %>% as.factor, y = n)
gg_sv1_col_1 <- gg_sv1_col_1 %+% geom_col()
gg_sv1_col_1 <- gg_sv1_col_1 %+% labs(title = "Satisfacción con la Vida")
gg_sv1_col_1 <- gg_sv1_col_1 %+% labs(subtitle = "count() y geom_col()")
gg_sv1_col_1 <- gg_sv1_col_1 %+% labs(x = "nivel de satisfacción")
gg_sv1_col_1 <- gg_sv1_col_1 %+% labs(y = "frecuencia")

library(patchwork)             # Permite sumar gráficos
gg_sv1_bar + gg_sv1_col_1

2.1.3 La variable estética fill

La variable fill determina el color de relleno de los polígonos que se estén graficando. En el contexto de un gráfico con geometría geom_col() determina el color de las barras. Esto permite visualizar información de una tercera variable adicional a x e y. Cuando fill sea definida por una variable numérica, el resultado será una escala de colores continua, en el caso de que sea definida por una variable categórica (por ejemplo, una variable clase factor) el resultado será una escala de colores discreta.

A continuación haremos un gráficos de barras usando las mismas variables x e y que en el gráfico anterior, pero definiendo fill como la variable DS_P1 que corresponde, según el manual al sexo de la persona encuestada. Utilizamos la función as.factor() para transformar el sexo a una variable categórica. Intenta omitir esta función y observa las diferencias ¿El resultado es una escala continua o discreta?

datos_sv1_wt <- datos_cep    %>% count(SV_1, DS_P1, wt = PONDERADOR)                            # Agragamos DS_P1
gg_sv1_col_2 <- datos_sv1_wt %>% ggplot() 
gg_sv1_col_2 <- gg_sv1_col_2 %+% aes(x = SV_1 %>% as.factor, y = n, fill = DS_P1 %>% as.factor) # Agregamos fill
gg_sv1_col_2 <- gg_sv1_col_2 %+% geom_col()
gg_sv1_col_2 <- gg_sv1_col_2 %+% labs(title = "Satisfacción con la Vida")
gg_sv1_col_2 <- gg_sv1_col_2 %+% labs(subtitle = "count(), aes(fill) y geom_col()")
gg_sv1_col_2 <- gg_sv1_col_2 %+% labs(x = "nivel de satisfacción")
gg_sv1_col_2 <- gg_sv1_col_2 %+% labs(y = "frecuencia")
gg_sv1_col_2 <- gg_sv1_col_2 %+% labs(fill = "sexo")                                            # Agregamos fill

gg_sv1_col_1 + gg_sv1_col_2

2.2 Definiendo la posición de las barras

Al utilizar la variable estética fill, ya sea usando la geometría geom_bar() o geom_col(), la posición por defecto de las barras (de distinto color) es estar apiladas una sobre otra, a esta posición se le llama stack. Existen otras posiciones posibles como dodge y fill, que las revisaremos a continuación.

2.2.1 Posición stack

Como venía diciendo, stack es la posición por defecto y sirve para ver cómo el valor de la variable y se divide entre dos o más categorías. Esta posición conserva la altura total de cada barra, es decir que permite ver la distribución de y sobre x, y al mismo tiempo como el valor de y se divide en las distintas categorías de fill, para cada valor de x.

El resultado de usar la posición stack es el mismo que obtuvimos en el gráfico anterior.

datos_sv1_wt <- datos_cep    %>% count(SV_1, DS_P1, wt = PONDERADOR)                             
gg_sv1_col_3 <- datos_sv1_wt %>% ggplot() 
gg_sv1_col_3 <- gg_sv1_col_3 %+% aes(x = SV_1 %>% as.factor, y = n, fill = DS_P1 %>% as.factor)  
gg_sv1_col_3 <- gg_sv1_col_3 %+% geom_col(position = "stack")                             # Agregamos la posición
gg_sv1_col_3 <- gg_sv1_col_3 %+% labs(title = "Satisfacción con la Vida")
gg_sv1_col_3 <- gg_sv1_col_3 %+% labs(subtitle = "count(), aes(fill) y geom_col(position = 'stack')")
gg_sv1_col_3 <- gg_sv1_col_3 %+% labs(x = "nivel de satisfacción")
gg_sv1_col_3 <- gg_sv1_col_3 %+% labs(y = "frecuencia")
gg_sv1_col_3 <- gg_sv1_col_3 %+% labs(fill = "sexo")                                           
gg_sv1_col_3

2.2.2 Posición dodge

Al usar la posición stack las barras correspondientes a las categorías de fill estaba apiladas una sobre otra. En cambio al usar la posición dodge las barras de cada categoría de fill se encuentran una al lado de la otra y cada barra parte desde el cero. Esta posición permite comparar visualmente el valor de la variable y entre las categorías de la variable fill.

Usando dodge es más fácil determinar si y (el conteo ponderado en nuestro ejemplo) es mayor entre hombres o mujeres que cuando las barras se encuentran apiladas.

datos_sv1_wt <- datos_cep    %>% count(SV_1, DS_P1, wt = PONDERADOR)                             
gg_sv1_col_4 <- datos_sv1_wt %>% ggplot() 
gg_sv1_col_4 <- gg_sv1_col_4 %+% aes(x = SV_1 %>% as.factor, y = n, fill = DS_P1 %>% as.factor)  
gg_sv1_col_4 <- gg_sv1_col_4 %+% geom_col(position = "dodge")                             # Agregamos la posición
gg_sv1_col_4 <- gg_sv1_col_4 %+% labs(title = "Satisfacción con la Vida")
gg_sv1_col_4 <- gg_sv1_col_4 %+% labs(subtitle = "count(), aes(fill) y geom_col(position = 'dodge')")
gg_sv1_col_4 <- gg_sv1_col_4 %+% labs(x = "nivel de satisfacción")
gg_sv1_col_4 <- gg_sv1_col_4 %+% labs(y = "frecuencia")
gg_sv1_col_4 <- gg_sv1_col_4 %+% labs(fill = "sexo")                                           

gg_sv1_col_4

Otra forma de definir la posición es untilizando una función de posición como position_dodge(). Esta función permite controlar aspectos estéticos de la posición como la separación entre las barras para un mismo valor de x usando el argumento width. Ejercicio: Reemplazar goem_col(position = 'dodge') por geom_col(position = position_dodge(width = 0.8)). ¿Notas alguna diferencia? ¿Qué ocurre si el width es mayor que 1? ¿Y si es negativo? Intenta distintas combinaciones

2.2.3 Posición fill

Ojo! no es lo mismo que la variable estética fill. Lo que hace la posición fill es parecido a cuando definimos la posición stack, pero normalizado por el valor total de y para cada categoría de x, el resultado son barras apiladas una sobre otra pero donde el valor total siempre suma 1, rellenando el espacio del eje y. Es ideal para poder visualizar proporciones en casos donde el valor total de y no es tan relevante.

datos_sv1_wt <- datos_cep    %>% count(SV_1, DS_P1, wt = PONDERADOR)                             
gg_sv1_col_5 <- datos_sv1_wt %>% ggplot() 
gg_sv1_col_5 <- gg_sv1_col_5 %+% aes(x = SV_1 %>% as.factor, y = n, fill = DS_P1 %>% as.factor)  
gg_sv1_col_5 <- gg_sv1_col_5 %+% geom_col(position = "fill")                              # Agregamos la posición
gg_sv1_col_5 <- gg_sv1_col_5 %+% labs(title = "Satisfacción con la Vida")
gg_sv1_col_5 <- gg_sv1_col_5 %+% labs(subtitle = "count(), aes(fill) y geom_col(position = 'fill')")
gg_sv1_col_5 <- gg_sv1_col_5 %+% labs(x = "nivel de satisfacción")
gg_sv1_col_5 <- gg_sv1_col_5 %+% labs(y = "frecuencia")
gg_sv1_col_5 <- gg_sv1_col_5 %+% labs(fill = "sexo")                                           
gg_sv1_col_5

```