Objetivos de la clase

Conocer las herramientas básicas que tenemos a nuestra disposición para dos de las fases clave en el análisis de datos: manejo y visualización.

¿Qué vamos a ver?

  • Qué es Tidyverse

  • Manejo de datos con dplyr

  • Funciones básicas de dplyr

  • Introducción a la visualización de datos con ggplot

  • Primeros gráficos con ggplot

1. Introducción a tidyverse

El paquete tidyverse en R es una colección de paquetes diseñados para trabajar de manera conjunta y ofrecer una experiencia consistente y coherente en el análisis de datos. Está compuesto por varios paquetes que abordan diferentes aspectos del análisis de datos, como manipulación de datos, visualización, modelado estadístico y programación.

Los paquetes principales que conforman tidyverse incluyen:

  1. ggplot2: Para visualización de datos, permite crear gráficos elegantes y personalizables.

  2. dplyr: Para manipulación de datos, proporciona funciones para filtrar, seleccionar, ordenar y resumir conjuntos de datos de manera eficiente.

  3. tidyr: Ayuda a convertir datos desordenados (wide) en ordenados (long) y viceversa, facilitando así el proceso de análisis y visualización.

  4. readr: Ofrece funciones para importar datos de diferentes formatos de archivo (como CSV, TSV, etc.) en R de manera rápida y eficiente.

  5. tibble: Proporciona una clase de datos (tibble) que mejora la visualización y manipulación de datos en comparación con los data frames tradicionales.

  6. purrr: Es una alternativa más consistente y eficiente a las funciones de iteración base de R, útil para trabajar con listas y aplicar funciones de manera más flexible.

  7. stringr: Ofrece funciones para manipular cadenas de texto de una manera más intuitiva y fácil de usar que las funciones base de R.

La filosofía subyacente de tidyverse se centra en la facilidad de uso, la consistencia y la eficiencia en el flujo de trabajo de análisis de datos, lo que lo convierte en una opción popular entre los científicos de datos y los analistas.

Como les indiqué antes de la clase, para instalar tidyverse debemos utilizar el siguiente código:

install.packages("tidyverse")

Una vez instalado, esto bastará para tener acceso al amplio cátalogo de herramientas que nos ofrece tidyverse. En esta sesión nos enfocaremos particularmente en dos de sus herramientas, dplyr y ggplot.

library(tidyverse)
## Warning: package 'ggplot2' was built under R version 4.3.2
## Warning: package 'tidyr' was built under R version 4.3.2
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.1.4     ✔ readr     2.1.5
## ✔ forcats   1.0.0     ✔ stringr   1.5.1
## ✔ ggplot2   3.5.0     ✔ tibble    3.2.1
## ✔ lubridate 1.9.3     ✔ tidyr     1.3.1
## ✔ purrr     1.0.2     
## ── 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

2.Manejo de datos con dplyr

2.1.Bases de datos

Las bases de datos tabulares son la manera más común de almacenar datos en campos como las ciencias sociales. Su utilidad radica en su capacidad para registrar múltiples aspectos de información para cada observación relevante. Es probable que hayas interactuado con este tipo de datos a través de herramientas como Microsoft Excel o Google Sheets. En estas tablas, la primera fila suele contener los nombres de las variables, indicando qué tipo de información está registrada en cada columna. Por otro lado, la primera columna se reserva para identificar las observaciones individuales.

Por ejemplo, pensemos en una encuesta que tenga diferentes variables de interes para nosotros, como los ingresos de la persona, caracterisiticas sociodemográficas y preferencias políticas.En el ejemplo, cada fila se refiere a una observación (es decir una persona encuestada) y cada columna a una caracteristica de esa persona.

##   id_observación sexo edad ingresos_miles milita_partido
## 1      persona_1    M   27            500             No
## 2      persona_2    F   45            700             Sí
## 3      persona_3    F   33            900             No

2.2.Operaciones básicas con dplyr

El paquete dplyr es una parte fundamental del tidyverse en R y se utiliza principalmente para la manipulación eficiente de datos. Ofrece un conjunto coherente de funciones que permiten realizar operaciones comunes de manera intuitiva y eficiente en conjuntos de datos.

Las principales funciones de dplyr incluyen:

  1. filter(): Permite seleccionar filas de un conjunto de datos que cumplan con ciertas condiciones.

  2. select(): Facilita la selección de columnas específicas de un conjunto de datos.

  3. mutate(): Agrega nuevas columnas a un conjunto de datos basadas en operaciones realizadas en columnas existentes.

  4. arrange(): Ordena las filas de un conjunto de datos según los valores de una o más columnas.

  5. summarize() / summarise(): Resumen de datos mediante la aplicación de funciones de agregación (como sum(), mean(), etc.) a columnas específicas.

  6. group_by(): Agrupa los datos según los valores únicos de una o más columnas, lo que permite realizar operaciones por grupos.

Estas funciones son muy poderosas y flexibles, y se pueden combinar fácilmente para realizar análisis de datos complejos de manera sencilla. Además, dplyr es conocido por su capacidad para manejar grandes volúmenes de datos de forma eficiente, lo que lo convierte en una herramienta invaluable para científicos de datos y analistas.

En esta sección iremos viendo cada una de estas herramientas en detalle.

Para utilizar las funciones del paquete dplyr, debemos llamarlo con la función library():

library(dplyr)

2.3.Preparando nuestro entorno de trabajo

Uno de los pasos más importantes antes de iniciar nuestro análisis, es tener claro en donde están alojados nuestros datos y en que carpetas que vamos a trabajar. Para esto es clave haber seguido los pasos que les indiqué antes de iniciar la clase.

Una vez hecho esto, vamos a nuestra caperta de trabajo y vamos a seleccionarla como nuestro directorio de trabajo

setwd("/Users/maco1304/Documents/curso_basicoR/Sesión 2 - manejo y visualización")

getwd()
## [1] "/Users/maco1304/Documents/curso_basicoR/Sesión 2 - manejo y visualización"

Esto nos falicitará trabajar con nuestro conjuntos de datos. Ahora abrimos nuestra base de datos, utilizando la función readxl (recordemos que debemos llamar la librería antes de llamar la función)

library(readxl)
datos <- read_excel("/Users/maco1304/Documents/curso_basicoR/Sesión 2 - manejo y visualización/inputs/datos_cantonales.xlsx")

datos
## # A tibble: 82 × 30
##    Nombre    PC PIB_cantonales `PIB Percápita` PIB_porce   IDH   IBM   IEV    IC
##    <chr>  <dbl>          <dbl>           <dbl>     <dbl> <dbl> <dbl> <dbl> <dbl>
##  1 SAN J…   101        9166134           26.4    0.251   0.758 0.642 0.876 0.775
##  2 ESCAZU   102        1013017           14.5    0.0278  0.867 0.852 0.905 0.846
##  3 DESAM…   103         852321            3.48   0.0234  0.743 0.604 0.860 0.789
##  4 PURIS…   104         117680            3.10   0.00322 0.755 0.600 0.941 0.761
##  5 TARRA…   105          72520            3.91   0.00199 0.668 0.517 0.839 0.687
##  6 ASERRI   106         140419            2.21   0.00385 0.737 0.600 0.816 0.818
##  7 MORA     107         121794            4.02   0.00334 0.801 0.747 0.858 0.800
##  8 GOICO…   108         878093            6.34   0.0241  0.758 0.623 0.880 0.796
##  9 SANTA…   109         770611           12.7    0.0211  0.871 0.852 0.935 0.828
## 10 ALAJU…   110         239551            2.53   0.00656 0.712 0.546 0.842 0.786
## # ℹ 72 more rows
## # ℹ 21 more variables: SalarioPE <dbl>, Poblacin <dbl>, Patentes2020 <dbl>,
## #   ICN21 <dbl>, IPS <chr>,
## #   `Índice de Gestión de Servicios Municipales 2021 (IGSM)` <chr>,
## #   ClasificacionPIB <chr>, IDH_Ajustado <dbl>, IDH_Ajustadoplus <dbl>,
## #   IDH_Ajustadopluso <dbl>, PIBz <dbl>, SalarioPEz <lgl>,
## #   `Trabajadores Seguro Salud (CCSS)` <dbl>, `Patronos (CCSS)` <dbl>, …

Este conjunto de datos es una recopilación de información cantonal como el IDH y servicios municipales hasta el último año disponible. Si utilizamos la función ncol()obtenemos el número de columnas y nrow el número de filas (observaciones).

ncol(datos)
## [1] 30
nrow(datos)
## [1] 82
str(datos)
## tibble [82 × 30] (S3: tbl_df/tbl/data.frame)
##  $ Nombre                                                : chr [1:82] "SAN JOSÉ" "ESCAZU" "DESAMPARADOS" "PURISCAL" ...
##  $ PC                                                    : num [1:82] 101 102 103 104 105 106 107 108 109 110 ...
##  $ PIB_cantonales                                        : num [1:82] 9166134 1013017 852321 117680 72520 ...
##  $ PIB Percápita                                         : num [1:82] 26.39 14.46 3.48 3.1 3.91 ...
##  $ PIB_porce                                             : num [1:82] 0.25116 0.02776 0.02335 0.00322 0.00199 ...
##  $ IDH                                                   : num [1:82] 0.758 0.867 0.743 0.755 0.668 ...
##  $ IBM                                                   : num [1:82] 0.642 0.852 0.604 0.6 0.517 ...
##  $ IEV                                                   : num [1:82] 0.876 0.905 0.86 0.941 0.839 ...
##  $ IC                                                    : num [1:82] 0.775 0.846 0.789 0.761 0.687 ...
##  $ SalarioPE                                             : num [1:82] 342630 642091 305576 301931 235289 ...
##  $ Poblacin                                              : num [1:82] 347398 70054 245208 37983 18535 ...
##  $ Patentes2020                                          : num [1:82] 16261 3151 4921 871 871 ...
##  $ ICN21                                                 : num [1:82] 63.4 68.3 59.2 55.6 61.5 54.5 62.7 60.1 63.8 51.2 ...
##  $ IPS                                                   : chr [1:82] "69.104687339864327" "74.571508779680684" "70.74943004350142" "68.3400563011797" ...
##  $ Índice de Gestión de Servicios Municipales 2021 (IGSM): chr [1:82] "Básico" "Básico" "Intermedio" "Intermedio" ...
##  $ ClasificacionPIB                                      : chr [1:82] "Muy Alto" "Muy Alto" "Alto" "Alto" ...
##  $ IDH_Ajustado                                          : num [1:82] 0.868 0.844 0.629 0.62 0.614 ...
##  $ IDH_Ajustadoplus                                      : num [1:82] 0.786 0.818 0.47 0.447 0.455 ...
##  $ IDH_Ajustadopluso                                     : num [1:82] 0.811 0.856 0.683 0.684 0.64 ...
##  $ PIBz                                                  : num [1:82] 0.962 0.785 0.366 0.332 0.401 ...
##  $ SalarioPEz                                            : logi [1:82] NA NA NA NA NA NA ...
##  $ Trabajadores Seguro Salud (CCSS)                      : num [1:82] 454668 47369 37845 7009 6478 ...
##  $ Patronos (CCSS)                                       : num [1:82] 14709 4846 1852 369 277 ...
##  $ UJ_2019 (BCCR)                                        : num [1:82] 19825 7682 3210 554 484 ...
##  $ Trabajadores_2019 (BCCR)                              : num [1:82] 64811 18993 8017 1077 618 ...
##  $ TrabaCCx1000hab                                       : num [1:82] 1308.8 67.6 15.4 18.5 35 ...
##  $ Patrox1000Hab                                         : num [1:82] 42.34 69.18 7.55 9.71 14.94 ...
##  $ UJ2019x1000hab                                        : num [1:82] 57.1 109.7 13.1 14.6 26.1 ...
##  $ Trabax1000Hab                                         : num [1:82] 186.6 271.1 32.7 28.4 33.3 ...
##  $ Patentesx1000hab                                      : num [1:82] 46.8 45 20.1 22.9 47 ...

2.4.Seleccionar columnas

Al trabajar con largos conjuntos de datos es común que nos encontramos con variables que no son de nuestro interés y queramos seleccionar solo aquellas que vamos a analizar. Para esto existe la función select(). En el conjunto de datos que ya tenemos cargados, como vimos hay 30 variables en total almacenadas como columnas,digamos que despúes de explorar nuestro datos nos damos cuenta que solo 5 de estas nos funcionan para nuestro análisis, estas son: PIB cantonal, IDH, Salario promedio, población y calificación servicios municipales. Obviamente tambien queremos seleccionar la columna que identifica los datos por cada cantón.

select(datos, Nombre, PC, PIB_cantonales, IDH, SalarioPE, Poblacin)
## # A tibble: 82 × 6
##    Nombre          PC PIB_cantonales   IDH SalarioPE Poblacin
##    <chr>        <dbl>          <dbl> <dbl>     <dbl>    <dbl>
##  1 SAN JOSÉ       101        9166134 0.758   342630.   347398
##  2 ESCAZU         102        1013017 0.867   642091.    70054
##  3 DESAMPARADOS   103         852321 0.743   305576.   245208
##  4 PURISCAL       104         117680 0.755   301931.    37983
##  5 TARRAZU        105          72520 0.668   235289.    18535
##  6 ASERRI         106         140419 0.737   301823.    63529
##  7 MORA           107         121794 0.801   468699.    30318
##  8 GOICOECHEA     108         878093 0.758   323370.   138525
##  9 SANTA ANA      109         770611 0.871   642091.    60453
## 10 ALAJUELITA     110         239551 0.712   256963.    94548
## # ℹ 72 more rows

Como ven la función no es muy compleja y sigue una sintaxis clara y simple (base de datos, variable1, variable2). Esta seguirá siendo la estructura básica para el uso de dplyr.

Noten que aunque la función nos retornó un resultado, no podemos hacer operaciones con estos datos, ya que no aplicamos la función a ningún objeto. Como recomendación general, nunca nunca (en serio nunca) modifiquen sus datos originales, no sabemos cuando sea necesario regresar a ellos. Ahora sí, queremos crear un nuevo objeto con las variables que nos resultan de interes.

datos2 <- select(datos, Nombre, PC, PIB_cantonales, IDH, SalarioPE, Poblacin,`Índice de Gestión de Servicios Municipales 2021 (IGSM)`)
datos2
## # A tibble: 82 × 7
##    Nombre      PC PIB_cantonales   IDH SalarioPE Poblacin Índice de Gestión de…¹
##    <chr>    <dbl>          <dbl> <dbl>     <dbl>    <dbl> <chr>                 
##  1 SAN JOSÉ   101        9166134 0.758   342630.   347398 Básico                
##  2 ESCAZU     102        1013017 0.867   642091.    70054 Básico                
##  3 DESAMPA…   103         852321 0.743   305576.   245208 Intermedio            
##  4 PURISCAL   104         117680 0.755   301931.    37983 Intermedio            
##  5 TARRAZU    105          72520 0.668   235289.    18535 Básico                
##  6 ASERRI     106         140419 0.737   301823.    63529 Intermedio            
##  7 MORA       107         121794 0.801   468699.    30318 Intermedio            
##  8 GOICOEC…   108         878093 0.758   323370.   138525 Básico                
##  9 SANTA A…   109         770611 0.871   642091.    60453 Básico                
## 10 ALAJUEL…   110         239551 0.712   256963.    94548 Intermedio            
## # ℹ 72 more rows
## # ℹ abbreviated name: ¹​`Índice de Gestión de Servicios Municipales 2021 (IGSM)`

Existen otras formas de seleccionar nuestras columnas. Supongamos que queremos las primeras cinco variables de nuestra base

select(datos, Nombre:PIB_porce) # forma recomendada
## # A tibble: 82 × 5
##    Nombre          PC PIB_cantonales `PIB Percápita` PIB_porce
##    <chr>        <dbl>          <dbl>           <dbl>     <dbl>
##  1 SAN JOSÉ       101        9166134           26.4    0.251  
##  2 ESCAZU         102        1013017           14.5    0.0278 
##  3 DESAMPARADOS   103         852321            3.48   0.0234 
##  4 PURISCAL       104         117680            3.10   0.00322
##  5 TARRAZU        105          72520            3.91   0.00199
##  6 ASERRI         106         140419            2.21   0.00385
##  7 MORA           107         121794            4.02   0.00334
##  8 GOICOECHEA     108         878093            6.34   0.0241 
##  9 SANTA ANA      109         770611           12.7    0.0211 
## 10 ALAJUELITA     110         239551            2.53   0.00656
## # ℹ 72 more rows
select(datos, 1:5)
## # A tibble: 82 × 5
##    Nombre          PC PIB_cantonales `PIB Percápita` PIB_porce
##    <chr>        <dbl>          <dbl>           <dbl>     <dbl>
##  1 SAN JOSÉ       101        9166134           26.4    0.251  
##  2 ESCAZU         102        1013017           14.5    0.0278 
##  3 DESAMPARADOS   103         852321            3.48   0.0234 
##  4 PURISCAL       104         117680            3.10   0.00322
##  5 TARRAZU        105          72520            3.91   0.00199
##  6 ASERRI         106         140419            2.21   0.00385
##  7 MORA           107         121794            4.02   0.00334
##  8 GOICOECHEA     108         878093            6.34   0.0241 
##  9 SANTA ANA      109         770611           12.7    0.0211 
## 10 ALAJUELITA     110         239551            2.53   0.00656
## # ℹ 72 more rows

La función select tambien nos ayuda a reordenar nuestras columnas, con solo seleccionar las variables en el orden que deseamos. Sin embargo esto es tedioso para largos conjuntos de datos, la función everything() nos ayuda a hacer esto más fácil. Digamos que solo queremos cambiar el orden del código geográfico y el nombre del cantón:

select(datos, PC, Nombre, everything())
## # A tibble: 82 × 30
##       PC Nombre PIB_cantonales `PIB Percápita` PIB_porce   IDH   IBM   IEV    IC
##    <dbl> <chr>           <dbl>           <dbl>     <dbl> <dbl> <dbl> <dbl> <dbl>
##  1   101 SAN J…        9166134           26.4    0.251   0.758 0.642 0.876 0.775
##  2   102 ESCAZU        1013017           14.5    0.0278  0.867 0.852 0.905 0.846
##  3   103 DESAM…         852321            3.48   0.0234  0.743 0.604 0.860 0.789
##  4   104 PURIS…         117680            3.10   0.00322 0.755 0.600 0.941 0.761
##  5   105 TARRA…          72520            3.91   0.00199 0.668 0.517 0.839 0.687
##  6   106 ASERRI         140419            2.21   0.00385 0.737 0.600 0.816 0.818
##  7   107 MORA           121794            4.02   0.00334 0.801 0.747 0.858 0.800
##  8   108 GOICO…         878093            6.34   0.0241  0.758 0.623 0.880 0.796
##  9   109 SANTA…         770611           12.7    0.0211  0.871 0.852 0.935 0.828
## 10   110 ALAJU…         239551            2.53   0.00656 0.712 0.546 0.842 0.786
## # ℹ 72 more rows
## # ℹ 21 more variables: SalarioPE <dbl>, Poblacin <dbl>, Patentes2020 <dbl>,
## #   ICN21 <dbl>, IPS <chr>,
## #   `Índice de Gestión de Servicios Municipales 2021 (IGSM)` <chr>,
## #   ClasificacionPIB <chr>, IDH_Ajustado <dbl>, IDH_Ajustadoplus <dbl>,
## #   IDH_Ajustadopluso <dbl>, PIBz <dbl>, SalarioPEz <lgl>,
## #   `Trabajadores Seguro Salud (CCSS)` <dbl>, `Patronos (CCSS)` <dbl>, …

2.5.Renombrar variables

Algunas de nuestras variables son tediosas de digitar o tal vez puedan ser muy largas para escribir nuestro código, facilmente la función rename nos ayuda con esto:

datos2 <- rename(datos2,
  "canton" = Nombre,
  "codigo" = PC,
  "pib_c" = PIB_cantonales,
  "idh" = IDH,
  "salario" = SalarioPE,
  "poblacion" = Poblacin,
  "igsm" = `Índice de Gestión de Servicios Municipales 2021 (IGSM)`
)
datos2
## # A tibble: 82 × 7
##    canton       codigo   pib_c   idh salario poblacion igsm      
##    <chr>         <dbl>   <dbl> <dbl>   <dbl>     <dbl> <chr>     
##  1 SAN JOSÉ        101 9166134 0.758 342630.    347398 Básico    
##  2 ESCAZU          102 1013017 0.867 642091.     70054 Básico    
##  3 DESAMPARADOS    103  852321 0.743 305576.    245208 Intermedio
##  4 PURISCAL        104  117680 0.755 301931.     37983 Intermedio
##  5 TARRAZU         105   72520 0.668 235289.     18535 Básico    
##  6 ASERRI          106  140419 0.737 301823.     63529 Intermedio
##  7 MORA            107  121794 0.801 468699.     30318 Intermedio
##  8 GOICOECHEA      108  878093 0.758 323370.    138525 Básico    
##  9 SANTA ANA       109  770611 0.871 642091.     60453 Básico    
## 10 ALAJUELITA      110  239551 0.712 256963.     94548 Intermedio
## # ℹ 72 more rows

2.6.Filtrar filas

Es común que algunas ocasiones queramos mantener solo cierto grupo de observaciones, o realizar operaciones con algunas de ellas basadas en sus caracteristicas. Antes de usar la función filter, es importantes familiarizarnos con los operadores lógicos de R:

Por ejemplo, despúes de realizar nuestro análisis, queremos solo prestar atención en aquellos cantones con un IDH bajo o muy bajo, para esto usamos la función filter() con el operador lógico que evalua la condición:

filter(datos2, idh <= 0.70)
## # A tibble: 27 × 7
##    canton      codigo  pib_c   idh salario poblacion igsm      
##    <chr>        <dbl>  <dbl> <dbl>   <dbl>     <dbl> <chr>     
##  1 TARRAZU        105  72520 0.668 235289.     18535 Básico    
##  2 DOTA           117  32379 0.660 217992.      7948 Básico    
##  3 LEON CORTES    120  75193 0.690 212233.     13769 Intermedio
##  4 SAN MATEO      204  36158 0.675 164544.      7141 Intermedio
##  5 UPALA          213 156532 0.678 226815.     54055 Intermedio
##  6 LOS CHILES     214 107667 0.640 190043.     33689 Básico    
##  7 SARAPIQUI      410 294717 0.688 244963.     83015 Intermedio
##  8 SANTA CRUZ     503 273947 0.693 274244.     68939 Básico    
##  9 BAGACES        504 176973 0.687 240917.     24130 Básico    
## 10 CARRILLO       505 196899 0.689 267271.     45939 Intermedio
## # ℹ 17 more rows

Tambien podemos aplicar filtros más complejos, digamos ahora que queremos no solo el idh menor a 0.70 y servicios municipales básico e intermedio

filter(datos2, idh <= 0.70 & igsm == "Intermedio")
## # A tibble: 12 × 7
##    canton      codigo  pib_c   idh salario poblacion igsm      
##    <chr>        <dbl>  <dbl> <dbl>   <dbl>     <dbl> <chr>     
##  1 LEON CORTES    120  75193 0.690 212233.     13769 Intermedio
##  2 SAN MATEO      204  36158 0.675 164544.      7141 Intermedio
##  3 UPALA          213 156532 0.678 226815.     54055 Intermedio
##  4 SARAPIQUI      410 294717 0.688 244963.     83015 Intermedio
##  5 CARRILLO       505 196899 0.689 267271.     45939 Intermedio
##  6 NANDAYURE      509  36681 0.687 201765.     11787 Intermedio
##  7 AGUIRRE        606 174604 0.680 239212.     33069 Intermedio
##  8 COTO BRUS      608 120214 0.683 229550.     44308 Intermedio
##  9 PARRITA        609  72701 0.685 226395.     20199 Intermedio
## 10 POCOCI         702 620573 0.700 243635.    150664 Intermedio
## 11 TALAMANCA      704 114182 0.601 211063.     43153 Intermedio
## 12 GUACIMO        706 187311 0.676 207824.     55128 Intermedio

Podemos pedirle solo aquellas observaciones con servicios básicos e intermedios:

filter(datos2, igsm == "Básico" | igsm == "Intermedio")
## # A tibble: 73 × 7
##    canton       codigo   pib_c   idh salario poblacion igsm      
##    <chr>         <dbl>   <dbl> <dbl>   <dbl>     <dbl> <chr>     
##  1 SAN JOSÉ        101 9166134 0.758 342630.    347398 Básico    
##  2 ESCAZU          102 1013017 0.867 642091.     70054 Básico    
##  3 DESAMPARADOS    103  852321 0.743 305576.    245208 Intermedio
##  4 PURISCAL        104  117680 0.755 301931.     37983 Intermedio
##  5 TARRAZU         105   72520 0.668 235289.     18535 Básico    
##  6 ASERRI          106  140419 0.737 301823.     63529 Intermedio
##  7 MORA            107  121794 0.801 468699.     30318 Intermedio
##  8 GOICOECHEA      108  878093 0.758 323370.    138525 Básico    
##  9 SANTA ANA       109  770611 0.871 642091.     60453 Básico    
## 10 ALAJUELITA      110  239551 0.712 256963.     94548 Intermedio
## # ℹ 63 more rows

Este resultado tambien lo podemos obtener si le pedimos que filtre todo lo que sea diferente de servicios municipales avanzados e iniciales

filter(datos2, igsm != "Avanzado")
## # A tibble: 75 × 7
##    canton       codigo   pib_c   idh salario poblacion igsm      
##    <chr>         <dbl>   <dbl> <dbl>   <dbl>     <dbl> <chr>     
##  1 SAN JOSÉ        101 9166134 0.758 342630.    347398 Básico    
##  2 ESCAZU          102 1013017 0.867 642091.     70054 Básico    
##  3 DESAMPARADOS    103  852321 0.743 305576.    245208 Intermedio
##  4 PURISCAL        104  117680 0.755 301931.     37983 Intermedio
##  5 TARRAZU         105   72520 0.668 235289.     18535 Básico    
##  6 ASERRI          106  140419 0.737 301823.     63529 Intermedio
##  7 MORA            107  121794 0.801 468699.     30318 Intermedio
##  8 GOICOECHEA      108  878093 0.758 323370.    138525 Básico    
##  9 SANTA ANA       109  770611 0.871 642091.     60453 Básico    
## 10 ALAJUELITA      110  239551 0.712 256963.     94548 Intermedio
## # ℹ 65 more rows

Una muy poderesa herramienta es filtrar según ciertas operaciones básicas que el sistema nos permite utilizar, digamos que queremos aquellas observaciones que sean mayores al promedio del IDH cantonal:

filter(datos2, idh > mean(idh))
## # A tibble: 41 × 7
##    canton       codigo   pib_c   idh salario poblacion igsm      
##    <chr>         <dbl>   <dbl> <dbl>   <dbl>     <dbl> <chr>     
##  1 SAN JOSÉ        101 9166134 0.758 342630.    347398 Básico    
##  2 ESCAZU          102 1013017 0.867 642091.     70054 Básico    
##  3 DESAMPARADOS    103  852321 0.743 305576.    245208 Intermedio
##  4 PURISCAL        104  117680 0.755 301931.     37983 Intermedio
##  5 ASERRI          106  140419 0.737 301823.     63529 Intermedio
##  6 MORA            107  121794 0.801 468699.     30318 Intermedio
##  7 GOICOECHEA      108  878093 0.758 323370.    138525 Básico    
##  8 SANTA ANA       109  770611 0.871 642091.     60453 Básico    
##  9 CORONADO        111  327391 0.801 383994.     71663 Básico    
## 10 TIBAS           113  368041 0.766 280816.     84873 Intermedio
## # ℹ 31 more rows

2.7. Encadenamiento de código y el operador pipe

Antes de seguir con las funciones que nos faltan, es un buen momento para presentarles a su nuevo mejor amigo, el operador pipe %<% o |>. El operador pipe es una función que nos permite concatenar código, ¿que quiere decir esto? esto quiere decir que en lugar de es escribir linea por linea varias operaciones que queramos realizar, podemos resumir todo en una misma acción. Como norma general, siempre vamos a querer que nuestro script sea lo más concreto posible, en esto el operador pipe es muy útil.

Para utilizar el operador pipe solo será necesario utilizar la siguiente combinación de teclas: shift + control + m (shift + command + m en Macbook).

Por ejemplo, no era necesario seleccionar nuestras columnas y filtrar los datos en operaciones de código seperada, todo lo que hemos hecho anteriormente lo podemos hacer en una misma acción:

# Vamos a seleccionar y filtrar los datos en una misma acción 
datos |> 
  select(Nombre, PC, PIB_cantonales, IDH, SalarioPE, Poblacin,`Índice de Gestión de Servicios Municipales 2021 (IGSM)`) |> 
  filter(IDH <= 0.70)
## # A tibble: 27 × 7
##    Nombre      PC PIB_cantonales   IDH SalarioPE Poblacin Índice de Gestión de…¹
##    <chr>    <dbl>          <dbl> <dbl>     <dbl>    <dbl> <chr>                 
##  1 TARRAZU    105          72520 0.668   235289.    18535 Básico                
##  2 DOTA       117          32379 0.660   217992.     7948 Básico                
##  3 LEON CO…   120          75193 0.690   212233.    13769 Intermedio            
##  4 SAN MAT…   204          36158 0.675   164544.     7141 Intermedio            
##  5 UPALA      213         156532 0.678   226815.    54055 Intermedio            
##  6 LOS CHI…   214         107667 0.640   190043.    33689 Básico                
##  7 SARAPIQ…   410         294717 0.688   244963.    83015 Intermedio            
##  8 SANTA C…   503         273947 0.693   274244.    68939 Básico                
##  9 BAGACES    504         176973 0.687   240917.    24130 Básico                
## 10 CARRILLO   505         196899 0.689   267271.    45939 Intermedio            
## # ℹ 17 more rows
## # ℹ abbreviated name: ¹​`Índice de Gestión de Servicios Municipales 2021 (IGSM)`

Incluso podemos renombrar las variables solo agregando una linea de código más que ejecutamos previamente:

datos |> 
  select(Nombre, PC, PIB_cantonales, IDH, SalarioPE, Poblacin,`Índice de Gestión de Servicios Municipales 2021 (IGSM)`) |> 
  filter(IDH <= 0.70) |> 
rename(
  "canton" = Nombre,
  "codigo" = PC,
  "pib_c" = PIB_cantonales,
  "idh" = IDH,
  "salario" = SalarioPE,
  "poblacion" = Poblacin,
  "igsm" = `Índice de Gestión de Servicios Municipales 2021 (IGSM)`
)
## # A tibble: 27 × 7
##    canton      codigo  pib_c   idh salario poblacion igsm      
##    <chr>        <dbl>  <dbl> <dbl>   <dbl>     <dbl> <chr>     
##  1 TARRAZU        105  72520 0.668 235289.     18535 Básico    
##  2 DOTA           117  32379 0.660 217992.      7948 Básico    
##  3 LEON CORTES    120  75193 0.690 212233.     13769 Intermedio
##  4 SAN MATEO      204  36158 0.675 164544.      7141 Intermedio
##  5 UPALA          213 156532 0.678 226815.     54055 Intermedio
##  6 LOS CHILES     214 107667 0.640 190043.     33689 Básico    
##  7 SARAPIQUI      410 294717 0.688 244963.     83015 Intermedio
##  8 SANTA CRUZ     503 273947 0.693 274244.     68939 Básico    
##  9 BAGACES        504 176973 0.687 240917.     24130 Básico    
## 10 CARRILLO       505 196899 0.689 267271.     45939 Intermedio
## # ℹ 17 more rows

Noten por favor que el nombre de nuestra base de datos ya no se indica dentro de la función, sino fuera de ella.

Ahora digamos que quisieramos acomodar nuestros datos según el idh, la función arrange() nos permite acomodar las observaciones sin ningún problema.

datos |> 
  select(Nombre, PC, PIB_cantonales, IDH, SalarioPE, Poblacin,`Índice de Gestión de Servicios Municipales 2021 (IGSM)`) |> 
  filter(IDH <= 0.70) |> 
rename(
  "canton" = Nombre,
  "codigo" = PC,
  "pib_c" = PIB_cantonales,
  "idh" = IDH,
  "salario" = SalarioPE,
  "poblacion" = Poblacin,
  "igsm" = `Índice de Gestión de Servicios Municipales 2021 (IGSM)`
) |> 
  arrange(idh)
## # A tibble: 27 × 7
##    canton       codigo  pib_c   idh salario poblacion igsm      
##    <chr>         <dbl>  <dbl> <dbl>   <dbl>     <dbl> <chr>     
##  1 MATINA          705 213096 0.579 166655.     46379 Básico    
##  2 LA CRUZ         510  66252 0.596 150528.     27090 Básico    
##  3 TALAMANCA       704 114182 0.601 211063.     43153 Intermedio
##  4 BUENOS AIRES    603 138837 0.620 178861.     53436 Avanzado  
##  5 HOJANCHA        511  20651 0.638 175531.      7998 Avanzado  
##  6 LOS CHILES      214 107667 0.640 190043.     33689 Básico    
##  7 DOTA            117  32379 0.660 217992.      7948 Básico    
##  8 TARRAZU         105  72520 0.668 235289.     18535 Básico    
##  9 SAN MATEO       204  36158 0.675 164544.      7141 Intermedio
## 10 GUACIMO         706 187311 0.676 207824.     55128 Intermedio
## # ℹ 17 more rows

por default la función ordena de menor a mayor, para ordenar en el sentido contrario podemos usar el “-” para indicar que queremos el orden inverso.

datos |> 
  select(Nombre, PC, PIB_cantonales, IDH, SalarioPE, Poblacin,`Índice de Gestión de Servicios Municipales 2021 (IGSM)`) |> 
  filter(IDH <= 0.70) |> 
rename(
  "canton" = Nombre,
  "codigo" = PC,
  "pib_c" = PIB_cantonales,
  "idh" = IDH,
  "salario" = SalarioPE,
  "poblacion" = Poblacin,
  "igsm" = `Índice de Gestión de Servicios Municipales 2021 (IGSM)`
) |> 
  arrange(-idh)
## # A tibble: 27 × 7
##    canton      codigo  pib_c   idh salario poblacion igsm      
##    <chr>        <dbl>  <dbl> <dbl>   <dbl>     <dbl> <chr>     
##  1 POCOCI         702 620573 0.700 243635.    150664 Intermedio
##  2 TILARAN        508 161856 0.696 231013.     21749 Avanzado  
##  3 CAÑAS          506 155507 0.695 232806.     32685 Inicial   
##  4 SANTA CRUZ     503 273947 0.693 274244.     68939 Básico    
##  5 PUNTARENAS     601 632077 0.692 244636.    140102 Avanzado  
##  6 GARABITO       611 130816 0.691 251251.     26028 Básico    
##  7 CORREDORES     610 160718 0.691 266683.     52419 Básico    
##  8 LEON CORTES    120  75193 0.690 212233.     13769 Intermedio
##  9 CARRILLO       505 196899 0.689 267271.     45939 Intermedio
## 10 LIMON          701 485556 0.688 265554.     99836 Básico    
## # ℹ 17 more rows

Nuevamente, no hemos aplicado ninguna de estas funciones a un objeto, por lo tanto no se guardan en la memoria de R. Digamos que de nuestro proceso de análisis concluimos que estos son los datos que utilizaremos para el resto de nuestro análisis, entonces aplicamos la función a un objeto

datos2 <- datos |> 
  select(Nombre, PC, PIB_cantonales, IDH, SalarioPE, Poblacin,`Índice de Gestión de Servicios Municipales 2021 (IGSM)`) |> 
  filter(IDH <= 0.70) |> 
rename(
  "canton" = Nombre,
  "codigo" = PC,
  "pib_c" = PIB_cantonales,
  "idh" = IDH,
  "salario" = SalarioPE,
  "poblacion" = Poblacin,
  "igsm" = `Índice de Gestión de Servicios Municipales 2021 (IGSM)`
) |> 
  arrange(-idh)

datos2
## # A tibble: 27 × 7
##    canton      codigo  pib_c   idh salario poblacion igsm      
##    <chr>        <dbl>  <dbl> <dbl>   <dbl>     <dbl> <chr>     
##  1 POCOCI         702 620573 0.700 243635.    150664 Intermedio
##  2 TILARAN        508 161856 0.696 231013.     21749 Avanzado  
##  3 CAÑAS          506 155507 0.695 232806.     32685 Inicial   
##  4 SANTA CRUZ     503 273947 0.693 274244.     68939 Básico    
##  5 PUNTARENAS     601 632077 0.692 244636.    140102 Avanzado  
##  6 GARABITO       611 130816 0.691 251251.     26028 Básico    
##  7 CORREDORES     610 160718 0.691 266683.     52419 Básico    
##  8 LEON CORTES    120  75193 0.690 212233.     13769 Intermedio
##  9 CARRILLO       505 196899 0.689 267271.     45939 Intermedio
## 10 LIMON          701 485556 0.688 265554.     99836 Básico    
## # ℹ 17 more rows

2.8.Crear y transformar variables

La mayor parte del tiempo vamos a querer crear y transformar variables a partir de las que ya tenemos, en nuestro conjuto de datos originales tenemos el porcentaje del aporte del PIB por cantón, sin embargo está en decimales, digamos que quisieramos transformamos la variables mulplicandola por 100.

datos |> 
  mutate(PIB_porce = PIB_porce*100)
## # A tibble: 82 × 30
##    Nombre    PC PIB_cantonales `PIB Percápita` PIB_porce   IDH   IBM   IEV    IC
##    <chr>  <dbl>          <dbl>           <dbl>     <dbl> <dbl> <dbl> <dbl> <dbl>
##  1 SAN J…   101        9166134           26.4     25.1   0.758 0.642 0.876 0.775
##  2 ESCAZU   102        1013017           14.5      2.78  0.867 0.852 0.905 0.846
##  3 DESAM…   103         852321            3.48     2.34  0.743 0.604 0.860 0.789
##  4 PURIS…   104         117680            3.10     0.322 0.755 0.600 0.941 0.761
##  5 TARRA…   105          72520            3.91     0.199 0.668 0.517 0.839 0.687
##  6 ASERRI   106         140419            2.21     0.385 0.737 0.600 0.816 0.818
##  7 MORA     107         121794            4.02     0.334 0.801 0.747 0.858 0.800
##  8 GOICO…   108         878093            6.34     2.41  0.758 0.623 0.880 0.796
##  9 SANTA…   109         770611           12.7      2.11  0.871 0.852 0.935 0.828
## 10 ALAJU…   110         239551            2.53     0.656 0.712 0.546 0.842 0.786
## # ℹ 72 more rows
## # ℹ 21 more variables: SalarioPE <dbl>, Poblacin <dbl>, Patentes2020 <dbl>,
## #   ICN21 <dbl>, IPS <chr>,
## #   `Índice de Gestión de Servicios Municipales 2021 (IGSM)` <chr>,
## #   ClasificacionPIB <chr>, IDH_Ajustado <dbl>, IDH_Ajustadoplus <dbl>,
## #   IDH_Ajustadopluso <dbl>, PIBz <dbl>, SalarioPEz <lgl>,
## #   `Trabajadores Seguro Salud (CCSS)` <dbl>, `Patronos (CCSS)` <dbl>, …

La función mutate() nos permite hacer multiples y variadas transformaciones a nuestros datos. Tambien podemos crear nuevas variables. En este caso, queremos transformar la variable PIB en una escala logarítmica.

datos |> 
  mutate(pib_log = log(PIB_cantonales)) |> 
  select(Nombre, PC, pib_log, everything())
## # A tibble: 82 × 31
##    Nombre        PC pib_log PIB_cantonales `PIB Percápita` PIB_porce   IDH   IBM
##    <chr>      <dbl>   <dbl>          <dbl>           <dbl>     <dbl> <dbl> <dbl>
##  1 SAN JOSÉ     101    16.0        9166134           26.4    0.251   0.758 0.642
##  2 ESCAZU       102    13.8        1013017           14.5    0.0278  0.867 0.852
##  3 DESAMPARA…   103    13.7         852321            3.48   0.0234  0.743 0.604
##  4 PURISCAL     104    11.7         117680            3.10   0.00322 0.755 0.600
##  5 TARRAZU      105    11.2          72520            3.91   0.00199 0.668 0.517
##  6 ASERRI       106    11.9         140419            2.21   0.00385 0.737 0.600
##  7 MORA         107    11.7         121794            4.02   0.00334 0.801 0.747
##  8 GOICOECHEA   108    13.7         878093            6.34   0.0241  0.758 0.623
##  9 SANTA ANA    109    13.6         770611           12.7    0.0211  0.871 0.852
## 10 ALAJUELITA   110    12.4         239551            2.53   0.00656 0.712 0.546
## # ℹ 72 more rows
## # ℹ 23 more variables: IEV <dbl>, IC <dbl>, SalarioPE <dbl>, Poblacin <dbl>,
## #   Patentes2020 <dbl>, ICN21 <dbl>, IPS <chr>,
## #   `Índice de Gestión de Servicios Municipales 2021 (IGSM)` <chr>,
## #   ClasificacionPIB <chr>, IDH_Ajustado <dbl>, IDH_Ajustadoplus <dbl>,
## #   IDH_Ajustadopluso <dbl>, PIBz <dbl>, SalarioPEz <lgl>,
## #   `Trabajadores Seguro Salud (CCSS)` <dbl>, `Patronos (CCSS)` <dbl>, …

Tambien podemos hacer operaciones entre variables, digamos que queremos hacer un indicador más robusto para los datos cantonales que incluya el IDH, el PIB y el salario. Vamos a crear una nueva variable que sea un promedio entre las 3 anteriores:

datos |> 
  mutate(indice_cantonal = IDH + PIB_cantonales + SalarioPE/3) |> 
   select(Nombre, PC, indice_cantonal, everything())
## # A tibble: 82 × 31
##    Nombre      PC indice_cantonal PIB_cantonales `PIB Percápita` PIB_porce   IDH
##    <chr>    <dbl>           <dbl>          <dbl>           <dbl>     <dbl> <dbl>
##  1 SAN JOSÉ   101        9280345.        9166134           26.4    0.251   0.758
##  2 ESCAZU     102        1227048.        1013017           14.5    0.0278  0.867
##  3 DESAMPA…   103         954180.         852321            3.48   0.0234  0.743
##  4 PURISCAL   104         218325.         117680            3.10   0.00322 0.755
##  5 TARRAZU    105         150950.          72520            3.91   0.00199 0.668
##  6 ASERRI     106         241027.         140419            2.21   0.00385 0.737
##  7 MORA       107         278028.         121794            4.02   0.00334 0.801
##  8 GOICOEC…   108         985884.         878093            6.34   0.0241  0.758
##  9 SANTA A…   109         984642.         770611           12.7    0.0211  0.871
## 10 ALAJUEL…   110         325206.         239551            2.53   0.00656 0.712
## # ℹ 72 more rows
## # ℹ 24 more variables: IBM <dbl>, IEV <dbl>, IC <dbl>, SalarioPE <dbl>,
## #   Poblacin <dbl>, Patentes2020 <dbl>, ICN21 <dbl>, IPS <chr>,
## #   `Índice de Gestión de Servicios Municipales 2021 (IGSM)` <chr>,
## #   ClasificacionPIB <chr>, IDH_Ajustado <dbl>, IDH_Ajustadoplus <dbl>,
## #   IDH_Ajustadopluso <dbl>, PIBz <dbl>, SalarioPEz <lgl>,
## #   `Trabajadores Seguro Salud (CCSS)` <dbl>, `Patronos (CCSS)` <dbl>, …

Ejercicio

Supogamos que la base de datos no incluye los datos del pib per capita por cantón y nos interesa crear esta nueva variable para nuestro análisis, escriba un código para crear un nuevo conjunto de datos, calcule el pib per capita cantonal y seleccione solo como variable el cantón, su código y la nueva variable:

2.9. la función summarize

La función summarize() nos permite realizar un proceso que a menudo lo llamamos colapso de datos. El proceso consiste en “resumir” nuestras filas en una sola fila a partir de alguna operación que se le aplique, supongamos que queremos calcular el promedio de IDH, PIB y Salario

datos |> 
  summarize(promedio_idh = mean(IDH),
            promedio_PIB = mean(PIB_cantonales),
            promedio_sal = mean(SalarioPE))
## # A tibble: 1 × 3
##   promedio_idh promedio_PIB promedio_sal
##          <dbl>        <dbl>        <dbl>
## 1        0.737      445064.      317099.

La función nos hizo un resumen de los datos a partir del calculo del promedio de cada una de las variables que solicitamos.

Resumenes por grupos

¡Esta es una de mis funciones favoritas! el proceso consiste nuevamente en colapsar nuestras filas de datos, pero agrupando según grupos que tengamos en nuestra base. Vamos a usar la función group_by().

Digamos que nos interesa conocer el promedio del IDH por cantón según el indice de gestión de servicios municipales (igsm). Recuerden que en datos2 ya tenemos estas variables renombradas para facilitar su escritura en el código, vamos a volver a usar datos2.

datos2 |> 
  group_by(igsm) |> 
  summarize(promedio_pib = mean(pib_c)) |> 
  arrange(promedio_pib)
## # A tibble: 4 × 2
##   igsm       promedio_pib
##   <chr>             <dbl>
## 1 Inicial         155507 
## 2 Básico          171992.
## 3 Intermedio      173814.
## 4 Avanzado        238355.

2.10.Recodificar variables

Un ejercicio común en la gestión de bases de datos es la generación de variables (o la edición de las ya existentes) basadas en ciertas condiciones lógicas. Ya construimos condiciones lógicas antes de usar filter(), así que la sintaxis general debería ser familiar.

Supongamos ahora que nos interesa realizar para nuestro análisis cierta tipología de cantones según su IDH. La combinación entre la función mutate() y case_when nos resuelve el problema de manera sencilla. Vamos a crear nuestros grupos siguiendo los siguientes criterios:

  • IDH alto mayor a 0.90
  • IDH medio menor a 0.80 pero mayor a 0.70
  • IDH bajo menor a 0.70

Notemos que estos mismos criterios se pueden “traducir” a R usando las condiciones lógicas:

datos |> 
  mutate(idh_grupos = case_when(
    IDH >= 0.90 ~ "Alto",
    IDH < 0.90 & IDH >= 0.80 ~ "Medio",
    IDH < .80 & IDH >= 0.70 ~ "Medio bajo",
    IDH < 0.70 ~ "Bajo",
    TRUE ~ NA
  )) |> 
  select(Nombre, IDH, idh_grupos, everything())
## # A tibble: 82 × 31
##    Nombre    IDH idh_grupos    PC PIB_cantonales `PIB Percápita` PIB_porce   IBM
##    <chr>   <dbl> <chr>      <dbl>          <dbl>           <dbl>     <dbl> <dbl>
##  1 SAN JO… 0.758 Medio bajo   101        9166134           26.4    0.251   0.642
##  2 ESCAZU  0.867 Medio        102        1013017           14.5    0.0278  0.852
##  3 DESAMP… 0.743 Medio bajo   103         852321            3.48   0.0234  0.604
##  4 PURISC… 0.755 Medio bajo   104         117680            3.10   0.00322 0.600
##  5 TARRAZU 0.668 Bajo         105          72520            3.91   0.00199 0.517
##  6 ASERRI  0.737 Medio bajo   106         140419            2.21   0.00385 0.600
##  7 MORA    0.801 Medio        107         121794            4.02   0.00334 0.747
##  8 GOICOE… 0.758 Medio bajo   108         878093            6.34   0.0241  0.623
##  9 SANTA … 0.871 Medio        109         770611           12.7    0.0211  0.852
## 10 ALAJUE… 0.712 Medio bajo   110         239551            2.53   0.00656 0.546
## # ℹ 72 more rows
## # ℹ 23 more variables: IEV <dbl>, IC <dbl>, SalarioPE <dbl>, Poblacin <dbl>,
## #   Patentes2020 <dbl>, ICN21 <dbl>, IPS <chr>,
## #   `Índice de Gestión de Servicios Municipales 2021 (IGSM)` <chr>,
## #   ClasificacionPIB <chr>, IDH_Ajustado <dbl>, IDH_Ajustadoplus <dbl>,
## #   IDH_Ajustadopluso <dbl>, PIBz <dbl>, SalarioPEz <lgl>,
## #   `Trabajadores Seguro Salud (CCSS)` <dbl>, `Patronos (CCSS)` <dbl>, …

Ejercicio

Agrupe según las siguientes condiciones:

  • Salario menor a 241597 = bajo
  • Salario mayor o igual 241597 pero menor a 294553 = medio bajo
  • Salario mayor o igual a 294553 pero menor a 383844 = medio alto
  • Salario mayor o igual a 383844 pero menor o igual a 642095 = alto

Con estos datos calcule el promedio según cada grupo:

3.Introducción a ggplot2

R cuenta con un gráficador base, que se llama plot, es muy útil para sacarnos de un apuro si queremos realizar gráficos rapidamente. Sin embargo, como la mayoría de funciones bases de R este tiene muchas limitaciones. El universo de tidyverse, pone a nuestra disposición el paquete ggplot2, el maravilloso gráficador que nos permite crear visualizaciones elegantes y con mucha personalidad con solo un par de lineas de código.

library(ggplot2)

Ggplot parte de una filosofía, que denominaremos “la grámatica de los gráficos (the grammar of graphics)” , según esto cualquier tipo de gráfico puede ser programado a partir de ciertos elementos comunes bajo una misma estructura de código.

Según la grámatica un gráfico estadístico es un mapeo de datos a atributos estéticos (color, forma, tamaño) de objetos geométricos (puntos, líneas, barras). El gráfico también puede contener transformaciones estadísticas de los datos y se dibuja en un sistema de coordenadas específico. El facetado puede utilizarse para generar el mismo gráfico para distintos subconjuntos del conjunto de datos. La combinación de estos componentes independientes es lo que constituye un gráfico (Wickham, 2011)

Cada uno de estos elementos tambien le llamaremos “capas”, elaborar un gráfico con ggplot no es más que sumar nuevas capas a nuestra visualización que aportan un elemento nuevo.

Sistema de capas en ggplot

Si lo queremos ver de otro modo, ggplot es como hornear un pastel

Primeros pasos para armar un gráfico con ggplot

Por esta vez vamos a utilizar para prácticar, los datos de a Agencia de Protección Ambiental de Estados Unidos que contiene datos de diferentes autos entre 1999 a 2008

datos_cars <- mpg
str(datos_cars)
## tibble [234 × 11] (S3: tbl_df/tbl/data.frame)
##  $ manufacturer: chr [1:234] "audi" "audi" "audi" "audi" ...
##  $ model       : chr [1:234] "a4" "a4" "a4" "a4" ...
##  $ displ       : num [1:234] 1.8 1.8 2 2 2.8 2.8 3.1 1.8 1.8 2 ...
##  $ year        : int [1:234] 1999 1999 2008 2008 1999 1999 2008 1999 1999 2008 ...
##  $ cyl         : int [1:234] 4 4 4 4 6 6 6 4 4 4 ...
##  $ trans       : chr [1:234] "auto(l5)" "manual(m5)" "manual(m6)" "auto(av)" ...
##  $ drv         : chr [1:234] "f" "f" "f" "f" ...
##  $ cty         : int [1:234] 18 21 20 21 16 18 18 18 16 20 ...
##  $ hwy         : int [1:234] 29 29 31 30 26 26 27 26 25 28 ...
##  $ fl          : chr [1:234] "p" "p" "p" "p" ...
##  $ class       : chr [1:234] "compact" "compact" "compact" "compact" ...

El primer paso es agregar las primeras dos capas a nuestro gráfico:

ggplot(datos_cars, aes(x = displ, y = hwy)) 

Los objetos geometricos en ggplot se refieren al tipo de gráfico que queremos hacer de acuerdo a la naturaleza de nuestros datos:

ggplot(datos_cars, aes(x = displ, y = hwy)) +
  geom_point()

Otros objetos geometricos usuales:

  • geom_line: Gráfico de lineas

  • geom_bar: Gráfico de barras

  • geom_boxplot: gráfico de barras y bigotes

  • geom_histogram: Histograma de frecuencias

Elementos esteticos: Formas, colores y tamaños

Con solo esos dos elementos, datos y mapeo estetico, podemos armar un gráfico más o menos decente que nos saque de un apuro. Sin embargo, conforme añadimos capas podemos agregar más personalidad a nuestro gráfico.

Las funciones shape, color, fill y size nos ayudan a dar mayor personalidad a nuestro gráfico

ggplot(datos_cars, aes(x = displ, y = hwy, color = manufacturer)) + 
  geom_point()

ggplot(datos_cars, aes(x = displ, y = hwy, color = manufacturer, size = class)) + 
  geom_point()

ggplot(datos_cars, aes(x = displ, y = hwy, color = manufacturer,size = class ,
                       shape = drv)) + 
  geom_point()

Ya para este momento, la gráfica tiene tantas capas que se ve demasiado saturada. Pero esta biblioteca da una infinidad de posibilidades.

Asimismo, ggplot2 también permite cambiar el color, tamaño y forma manualmente (sin que representen una variable). Lo único diferente que hay que hacer es definir esas variables fuera del comando aes()

ggplot(datos_cars, aes(x = displ, y = hwy)) + 
         geom_point(color = "skyblue1", size = 4)

Gráficos de barras

Vamos a cargar la base alcaldias de nuestra carpeta:

alcaldias <- read_excel("/Users/maco1304/Documents/curso_basicoR/Sesión 2 - manejo y visualización/inputs/Alcaldias.xlsx")

Los datos contienen las alcaldias ganadas por partidos políticos que han estado en el gobiero desde el 2002, vamos a hacer un gráfico de barras con estos datos, recordemos lo primero que tenemos que hacer es añadir las primeras dos capas, datos y mapeo estetico.

ggplot(alcaldias, aes(x = anio, y = total)) +
  geom_bar(stat = "identity")

mmmm de ante mano pareciera que algo no salió bien verdad ?, lo que sucede es que no específicamos al programa que hay una tercera variable a considerar, llamada partido. Estos lo específicamos con el argumento fill =.

ggplot(alcaldias, aes(x = anio, y = total, fill = partido)) +
  geom_bar(stat = "identity")

Un poco mejor, sin embargo sigue sin convencerme que esta sea la mejor forma de visualizar el gráfico. Podemos seleccionar entre barras apiladas y agrupadas:

ggplot(alcaldias, aes(x = anio, y = total, fill = partido)) +
  geom_bar(stat = "identity", position = "dodge")

Va mejor, pero aún puede, mejorar. La función scale_fill_manual nos permite colorear a volutad con nuestra propia paleta de colores. Además en algunos casos es conveniente convertir la variable año a tipo factor, para evitar saltos dispares en la continuidad del eje x:

ggplot(alcaldias, aes(x = factor(anio), y = total, fill = partido)) +
  geom_bar(stat = "identity", position = "dodge") +
  scale_fill_manual(values = c("#624887","#fbd020", "#39aa47", "#0b4a8e"))

Podemos ajustar los titulos de los ejes y el titulo, subtitulo del gráfico

ggplot(alcaldias, aes(x = factor(anio), y = total, fill = partido)) +
  geom_bar(stat = "identity", position = "dodge") +
  scale_fill_manual(values = c("#624887","#fbd020", "#39aa47", "#0b4a8e")) +
  labs(x = "Año", y = "Alcaldias", title = "Gráfico 1.",
       subtitle = "Municipalidades ganadas por año según partido político (2002-2020)")

Gráficos de lineas

Abrimos un nuevo conjuto de datos

datos_parti <- read_excel("/Users/maco1304/Documents/curso_basicoR/Sesión 2 - manejo y visualización/inputs/datos_parti.xlsx")

A partir del conjunto de datos, hacemos nuestro nuevo gráfico

# Gráfico de lineas
plot <- ggplot(datos_parti,aes(x = anio, y = porcentaje)) +
  geom_line(aes(group = eleccion_tipo, color = eleccion_tipo), linewidth = 1.5) +
  geom_point(size = 2, color = "grey33") +
  scale_y_continuous(labels = scales::percent_format()) +
  scale_color_manual(values = c("#1380A1", "#ce5217")) +
  labs(x = "Años de elección",y = "Porcentaje")

plot

Tarea para despúes de semana santa :)

Exploren datos cantonales y electorales de su cantón de empadronamiento y piensen en formas de manejar y visualizar esos datos.

Sugerencias: Participación por año, votos por distrito, votos del partido ganador, conformación partidaria del Consejo Municipal, etc.

La idea del ejercicio es explorar un poco más lo que hemos visto y desarrollar intuitivamente como aplicar las herramientas que tenemos. Si tienen alguna dificultas lo vemos despúes de semana santa, yo ya lo tengo hecho para mi caso entonces vamos a ver sugerencias de cómo entrarle a esto en la siguiente clase.