\[ \]

Introducción

En esta clase vamos a aprender a usar algunos paquetes para limpiar datos y estructurar información en R. Pero, antes de ello, es importante recordar como realizar pequeños análisis exploratorio de los datos. Este primer paso consiste en explorar las variables de nuestra base de datos para:

  • Encontrar patrones
  • Identificar errores
  • Plantear nuevas hipótesis o preguntas
  • Identificar relaciones entre variables
  • Empezar a encontrar respuestas a nuestras preguntas de investigación

Es importante considerar que primer paso no corresponde a un análisis estadístico riguroso, pero puede permitirnos encontrar respuestas o guiarnos en el tipo de análisis que queremos realizar.

Explorar los datos

Para esta primer ejercicio vamos a usar la base de datos denominada encuesta

Antes de comenzar, hay que cambiar el directorio de trabajo y seleccionar el folder en donde tenemos nuestros archivos. Esto se hace con el comando setwd() .

#Cambiar el directorio de trabajo 
setwd("C:/Users/Administrador/Dropbox/UCARIBE/2021/CD/Limpieza de datos")
Encuesta <- read.csv("Encuesta.csv",sep=",")
head(Encuesta)
##        ID Genero Estado_civil Nivel_escolaridad Ingreso  Tipo_vivienda
## 1 00H5878 Hombre     Viudo(a)                 3    8000      Alquilada
## 2 00H5342 Hombre  Separado(a)                 5    5500       Prestada
## 3 00H5464 Hombre    Casado(a)                 3    6500 Propia pagando
## 4 00H5498 Hombre   Soltero(a)                 3   17500      Alquilada
## 5 00M4648  Mujer   Soltero(a)                 2   15900      Alquilada
## 6 00H5308 Hombre     Viudo(a)                 4   19100      Alquilada
##   Mensualidad Region   Zona
## 1        8100    Sur Urbana
## 2          NA  Norte Urbana
## 3          NA    Sur Urbana
## 4        5700    Sur Urbana
## 5        5600    Sur Urbana
## 6        9200  Norte  Rural

Los datos tienen las siguientes variables:

  • id: identificador único.

  • Género: (Hombre o Mujer).

  • Estado civil: (Soltero(a), Viudo(a), Separado(a), Casado(a), Union libre).

  • Nivel escolar: (0: sin nivel educativo o primeria incompleta, 1: Primaria completa o secundaria incompleta, 2: Secundaria completa o preparatoria incompleta, 3: Preparatoria completa o licenciatura incompleta, 4: Licenciatura completa o posgrado incompleto, 5: Posgrado terminado).

  • Ingreso: ingreso neto mensual.

  • Tipo de vivienda: (Propia, Propia pagando, Alquilada, Prestada, Otro)

  • Mensualidad: Mensualidad pagada por la vivienda, cuando esta no es propia.

  • Región: región en el país donde vive la persona (Norte, Centro, Sur)

  • Zona: zona donde vive la persona (Urbana o Rural).

library(dplyr)
glimpse(Encuesta)
## Rows: 1,500
## Columns: 9
## $ ID                <chr> "00H5878", "00H5342", "00H5464", "00H5498", "00M4...
## $ Genero            <chr> "Hombre", "Hombre", "Hombre", "Hombre", "Mujer", ...
## $ Estado_civil      <chr> "Viudo(a)", "Separado(a)", "Casado(a)", "Soltero(...
## $ Nivel_escolaridad <int> 3, 5, 3, 3, 2, 4, 2, 5, 4, 3, 3, 5, 4, 5, 4, 4, 5...
## $ Ingreso           <int> 8000, 5500, 6500, 17500, 15900, 19100, 14900, 120...
## $ Tipo_vivienda     <chr> "Alquilada", "Prestada", "Propia pagando", "Alqui...
## $ Mensualidad       <int> 8100, NA, NA, 5700, 5600, 9200, 5200, NA, 7200, N...
## $ Region            <chr> "Sur", "Norte", "Sur", "Sur", "Sur", "Norte", "Su...
## $ Zona              <chr> "Urbana", "Urbana", "Urbana", "Urbana", "Urbana",...

Con esto podemos ver que tenemos tres variables numericas (int) y el resto con caracteres o texto.

Recordemos que también hay otros comandos exploratorios como: str(), head(), tail(), class().

Podemos convertir las variables de texto a factores (variables con categorías) con el comando as.factor(). Por ejemplo si queremos convertir la variable de Genero, sería:

Encuesta$Genero <- as.factor(Encuesta$Genero)

str(Encuesta)
## 'data.frame':    1500 obs. of  9 variables:
##  $ ID               : chr  "00H5878" "00H5342" "00H5464" "00H5498" ...
##  $ Genero           : Factor w/ 2 levels "Hombre","Mujer": 1 1 1 1 2 1 2 1 1 1 ...
##  $ Estado_civil     : chr  "Viudo(a)" "Separado(a)" "Casado(a)" "Soltero(a)" ...
##  $ Nivel_escolaridad: int  3 5 3 3 2 4 2 5 4 3 ...
##  $ Ingreso          : int  8000 5500 6500 17500 15900 19100 14900 12000 19300 8600 ...
##  $ Tipo_vivienda    : chr  "Alquilada" "Prestada" "Propia pagando" "Alquilada" ...
##  $ Mensualidad      : int  8100 NA NA 5700 5600 9200 5200 NA 7200 NA ...
##  $ Region           : chr  "Sur" "Norte" "Sur" "Sur" ...
##  $ Zona             : chr  "Urbana" "Urbana" "Urbana" "Urbana" ...

Ahora, si queremos convertir varias variables a factor, sería:

col<- c("Genero","Estado_civil","Nivel_escolaridad","Tipo_vivienda","Region", "Zona" )
# Aplicamos una misma función a todas las columnas con lapply  
Encuesta[col] <- lapply(Encuesta[col], factor)

glimpse(Encuesta)
## Rows: 1,500
## Columns: 9
## $ ID                <chr> "00H5878", "00H5342", "00H5464", "00H5498", "00M4...
## $ Genero            <fct> Hombre, Hombre, Hombre, Hombre, Mujer, Hombre, Mu...
## $ Estado_civil      <fct> Viudo(a), Separado(a), Casado(a), Soltero(a), Sol...
## $ Nivel_escolaridad <fct> 3, 5, 3, 3, 2, 4, 2, 5, 4, 3, 3, 5, 4, 5, 4, 4, 5...
## $ Ingreso           <int> 8000, 5500, 6500, 17500, 15900, 19100, 14900, 120...
## $ Tipo_vivienda     <fct> Alquilada, Prestada, Propia pagando, Alquilada, A...
## $ Mensualidad       <int> 8100, NA, NA, 5700, 5600, 9200, 5200, NA, 7200, N...
## $ Region            <fct> Sur, Norte, Sur, Sur, Sur, Norte, Sur, Norte, Sur...
## $ Zona              <fct> Urbana, Urbana, Urbana, Urbana, Urbana, Rural, Ur...

Variables categóricas

Para las variables categóricas, una forma de explorar su comportamiento espor medio de tablas de frecuencia, es decir, ver el número de ocurrencias de cada categoría de la variable. Esto lo hacemos con el comando table().

# Tablas de frecuencia
table(Encuesta$Genero)
## 
## Hombre  Mujer 
##   1038    462
table(Encuesta$Estado_civil)
## 
##   Casado(a) Separado(a)  Soltero(a) Union libre    Viudo(a) 
##         543         288         436         135          98
table(Encuesta$Region)
## 
## Centro  Norte    Sur 
##    260    415    825
table(Encuesta$Zona)
## 
##  Rural Urbana 
##    412   1088
# Tablas de contingencia
table(Encuesta$Genero, Encuesta$Estado_civil)
##         
##          Casado(a) Separado(a) Soltero(a) Union libre Viudo(a)
##   Hombre       379         206        295          90       68
##   Mujer        164          82        141          45       30
table(Encuesta$Tipo_vivienda, Encuesta$Zona)
##                 
##                  Rural Urbana
##   Alquilada        156    443
##   Otro              40    117
##   Prestada          43    106
##   Propia            47     95
##   Propia pagando   126    327

Los números absolutos a veces no son útiles para entender los datos, por lo que es mejor utilizar proporciones. Para ello usamos el comando prop.table().

Por ejemplo si quisieramos ver las tablas anteriores como proporciones:

prop.table(table(Encuesta$Genero))
## 
## Hombre  Mujer 
##  0.692  0.308
prop.table(table(Encuesta$Estado_civil))
## 
##   Casado(a) Separado(a)  Soltero(a) Union libre    Viudo(a) 
##  0.36200000  0.19200000  0.29066667  0.09000000  0.06533333
prop.table(table(Encuesta$Region))
## 
##    Centro     Norte       Sur 
## 0.1733333 0.2766667 0.5500000
prop.table(table(Encuesta$Zona))
## 
##     Rural    Urbana 
## 0.2746667 0.7253333
round(prop.table(table(Encuesta$Genero, Encuesta$Estado_civil)),2)
##         
##          Casado(a) Separado(a) Soltero(a) Union libre Viudo(a)
##   Hombre      0.25        0.14       0.20        0.06     0.05
##   Mujer       0.11        0.05       0.09        0.03     0.02
round(prop.table(table(Encuesta$Tipo_vivienda, Encuesta$Zona)),2)
##                 
##                  Rural Urbana
##   Alquilada       0.10   0.30
##   Otro            0.03   0.08
##   Prestada        0.03   0.07
##   Propia          0.03   0.06
##   Propia pagando  0.08   0.22

En este caso nos muestra los datos como proporciones totales, pero ¿cómo hacemos si queremos ver porcentajes por fila o columna?. Esto lo hacemos poniendo una coma y luego 1 (filas) o 2 (columnas).

# Filas
round(prop.table(table(Encuesta$Tipo_vivienda, Encuesta$Zona),1),2)
##                 
##                  Rural Urbana
##   Alquilada       0.26   0.74
##   Otro            0.25   0.75
##   Prestada        0.29   0.71
##   Propia          0.33   0.67
##   Propia pagando  0.28   0.72
# Columnas
round(prop.table(table(Encuesta$Tipo_vivienda, Encuesta$Zona),2),2)
##                 
##                  Rural Urbana
##   Alquilada       0.38   0.41
##   Otro            0.10   0.11
##   Prestada        0.10   0.10
##   Propia          0.11   0.09
##   Propia pagando  0.31   0.30

Un comando muy útil para simplificar los pasos es el comando CrossTable() del paquete gmodels. El comando nos permite presentar en una misma tabla los porcentajes por fila o columna y el total de la tabla.

require(gmodels) # analogo a library
# Crosstable
CrossTable(Encuesta$Zona)
## 
##  
##    Cell Contents
## |-------------------------|
## |                       N |
## |         N / Table Total |
## |-------------------------|
## 
##  
## Total Observations in Table:  1500 
## 
##  
##           |     Rural |    Urbana | 
##           |-----------|-----------|
##           |       412 |      1088 | 
##           |     0.275 |     0.725 | 
##           |-----------|-----------|
## 
## 
## 
## 
CrossTable(Encuesta$Tipo_vivienda, Encuesta$Zona, prop.chisq = F)
## 
##  
##    Cell Contents
## |-------------------------|
## |                       N |
## |           N / Row Total |
## |           N / Col Total |
## |         N / Table Total |
## |-------------------------|
## 
##  
## Total Observations in Table:  1500 
## 
##  
##                        | Encuesta$Zona 
## Encuesta$Tipo_vivienda |     Rural |    Urbana | Row Total | 
## -----------------------|-----------|-----------|-----------|
##              Alquilada |       156 |       443 |       599 | 
##                        |     0.260 |     0.740 |     0.399 | 
##                        |     0.379 |     0.407 |           | 
##                        |     0.104 |     0.295 |           | 
## -----------------------|-----------|-----------|-----------|
##                   Otro |        40 |       117 |       157 | 
##                        |     0.255 |     0.745 |     0.105 | 
##                        |     0.097 |     0.108 |           | 
##                        |     0.027 |     0.078 |           | 
## -----------------------|-----------|-----------|-----------|
##               Prestada |        43 |       106 |       149 | 
##                        |     0.289 |     0.711 |     0.099 | 
##                        |     0.104 |     0.097 |           | 
##                        |     0.029 |     0.071 |           | 
## -----------------------|-----------|-----------|-----------|
##                 Propia |        47 |        95 |       142 | 
##                        |     0.331 |     0.669 |     0.095 | 
##                        |     0.114 |     0.087 |           | 
##                        |     0.031 |     0.063 |           | 
## -----------------------|-----------|-----------|-----------|
##         Propia pagando |       126 |       327 |       453 | 
##                        |     0.278 |     0.722 |     0.302 | 
##                        |     0.306 |     0.301 |           | 
##                        |     0.084 |     0.218 |           | 
## -----------------------|-----------|-----------|-----------|
##           Column Total |       412 |      1088 |      1500 | 
##                        |     0.275 |     0.725 |           | 
## -----------------------|-----------|-----------|-----------|
## 
## 

Tambien podemos simplificar la tabla para que nos muestre menos resultados, cambiando las opciones:

  • prop.r=T: porcentaje por filas. Si lo ponemos = F no lo muestra.
  • prop.c=T: porcentaje por columnas. Si lo ponemos = F no lo muestra
  • prop.t=T: porcentaje total de la tabla. Si lo ponemos = F no lo muestra

Variables numéricas

Para calcular los estadísticos de las variables numéricas tenemos varias opciones.

Podemos usar el comando summary(). Este comando nos da los principales estadísticos descriptivos (mínimo, máximo, cuartiles, promedio,mediana). Este comando podemos aplicarlo a todo el dataframe (nos da los estadísticos de todas las variables a la vez) o solo a una variable.

summary(Encuesta)
##       ID               Genero          Estado_civil Nivel_escolaridad
##  Length:1500        Hombre:1038   Casado(a)  :543   0: 61            
##  Class :character   Mujer : 462   Separado(a):288   1: 71            
##  Mode  :character                 Soltero(a) :436   2:163            
##                                   Union libre:135   3:419            
##                                   Viudo(a)   : 98   4:446            
##                                                     5:340            
##                                                                      
##     Ingreso             Tipo_vivienda  Mensualidad       Region   
##  Min.   : 1000   Alquilada     :599   Min.   : 5000   Centro:260  
##  1st Qu.: 6975   Otro          :157   1st Qu.: 6100   Norte :415  
##  Median :10750   Prestada      :149   Median : 7500   Sur   :825  
##  Mean   :10736   Propia        :142   Mean   : 7473               
##  3rd Qu.:14400   Propia pagando:453   3rd Qu.: 8800               
##  Max.   :21300                        Max.   :10000               
##                                       NA's   :901                 
##      Zona     
##  Rural : 412  
##  Urbana:1088  
##               
##               
##               
##               
## 
summary(Encuesta$Ingreso)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##    1000    6975   10750   10736   14400   21300

Un comando muy útil es describe() del paquete Hmisc, ya que nos muestra un panorama más completo de las variables. En el caso de las numéricas nos muestra los estadísticos descriptivos, la cantidad de observaciones, los valores perdidos. Para las variables categóricas, muestra la frecuencia, las proporciones y los valores perdidos.

require(Hmisc) 

describe(Encuesta)
## Encuesta 
## 
##  9  Variables      1500  Observations
## --------------------------------------------------------------------------------
## ID 
##        n  missing distinct 
##     1500        0      841 
## 
## lowest : 00H5000 00H5002 00H5004 00H5008 00H5010
## highest: 00M6952 00M6954 00M6958 00M6970 00M6974
## --------------------------------------------------------------------------------
## Genero 
##        n  missing distinct 
##     1500        0        2 
##                         
## Value      Hombre  Mujer
## Frequency    1038    462
## Proportion  0.692  0.308
## --------------------------------------------------------------------------------
## Estado_civil 
##        n  missing distinct 
##     1500        0        5 
## 
## lowest : Casado(a)   Separado(a) Soltero(a)  Union libre Viudo(a)   
## highest: Casado(a)   Separado(a) Soltero(a)  Union libre Viudo(a)   
##                                                                       
## Value        Casado(a) Separado(a)  Soltero(a) Union libre    Viudo(a)
## Frequency          543         288         436         135          98
## Proportion       0.362       0.192       0.291       0.090       0.065
## --------------------------------------------------------------------------------
## Nivel_escolaridad 
##        n  missing distinct 
##     1500        0        6 
## 
## lowest : 0 1 2 3 4, highest: 1 2 3 4 5
##                                               
## Value          0     1     2     3     4     5
## Frequency     61    71   163   419   446   340
## Proportion 0.041 0.047 0.109 0.279 0.297 0.227
## --------------------------------------------------------------------------------
## Ingreso 
##        n  missing distinct     Info     Mean      Gmd      .05      .10 
##     1500        0      204        1    10736     5963     2300     3400 
##      .25      .50      .75      .90      .95 
##     6975    10750    14400    18300    19805 
## 
## lowest :  1000  1100  1200  1300  1400, highest: 20900 21000 21100 21200 21300
## --------------------------------------------------------------------------------
## Tipo_vivienda 
##        n  missing distinct 
##     1500        0        5 
## 
## lowest : Alquilada      Otro           Prestada       Propia         Propia pagando
## highest: Alquilada      Otro           Prestada       Propia         Propia pagando
##                                                                       
## Value           Alquilada           Otro       Prestada         Propia
## Frequency             599            157            149            142
## Proportion          0.399          0.105          0.099          0.095
##                          
## Value      Propia pagando
## Frequency             453
## Proportion          0.302
## --------------------------------------------------------------------------------
## Mensualidad 
##        n  missing distinct     Info     Mean      Gmd      .05      .10 
##      599      901       51        1     7473     1705     5200     5500 
##      .25      .50      .75      .90      .95 
##     6100     7500     8800     9500     9800 
## 
## lowest :  5000  5100  5200  5300  5400, highest:  9600  9700  9800  9900 10000
## --------------------------------------------------------------------------------
## Region 
##        n  missing distinct 
##     1500        0        3 
##                                
## Value      Centro  Norte    Sur
## Frequency     260    415    825
## Proportion  0.173  0.277  0.550
## --------------------------------------------------------------------------------
## Zona 
##        n  missing distinct 
##     1500        0        2 
##                         
## Value       Rural Urbana
## Frequency     412   1088
## Proportion  0.275  0.725
## --------------------------------------------------------------------------------

Limpieza de datos

Paquetes vamos a necesitar:

library(dplyr)
library(tidyr) 
library(readxl)

Los archivos que vamos a usar inicialmente son:

morosidad16 <- read_xlsx("morosidad16.xlsx")
morosidad17 <- read_xlsx("morosidad17.xlsx")

Antes de comenzar a limpiar o analizar los datos tenemos que explorar los datos. Para este ejercicio vamos a usar las bases de datos de morosidad del 2016 y 2017.

Ambas bases de datos tienen las siguientes variables:

  • id: registro único.
  • nombre: Nombre de la persona física o jurídica.
  • deuda16 y deuda17 : monto de la deuda en colones.
  • situación: situación en la que se encuentra la deuda.
  • lugar.pago: sucursal donde se tiene que cancelar la deuda.
  • Estado: Estado de la deuda.

Cómo primer paso vamos a unir ambas bases de datos. Para unir bases de datos necesitamos una o más variables en común entre las dos bases de datos. Existen varias funciones para unir bases de datos. Una de ellas es merge(), que sirve para unir columnas de dos bases de datos diferentes. Para unir bases es clave hacerse la pregunta: ¿Queremos conservar todas las variables o solo las que hacen match?. De acuerdo a la respuesta, así va a depender la fórmula que usemos.

La sintaxis de merge() es simple:

merge(base1, base2, by.x="nombre variable base 1", by.y="nombre variable base 2")

En el caso en el que la variable se llame igual en las dos bases:

merge(base1, base2, by="nombre variable")

En esos ejemplos, el comando une solamente los casos en común entre las dos bases. Si queremos que se unan todos los casos, usamos la opción all=TRUE:

merge(base1, base2, by="nombre variable", all=TRUE)

Pueden ver este documento donde se muestra cómo funciona esta función con detalle. Link

Para este ejercicio queremos unir las dos bases de morosidad en una sola, dejando todas las observaciones de ambas bases, entonces usamos el comando:

morosidad<-merge(morosidad17, morosidad16, by= "id", all=TRUE)

Ahora podemos convertir la base a una tibble() para facilitar la lectura:

morosidad <-tbl_df(morosidad)

Si queremos imprimir la base de datos, nada más ponemos el nombre del objeto:

morosidad
## # A tibble: 78,703 x 10
##        id nombre.x deuda17 situacion.x lugar.pago.x Estado nombre.y deuda16
##     <dbl> <chr>      <dbl> <chr>       <chr>        <chr>  <chr>      <dbl>
##  1 0.     VAN ADE~  265838 DIFICIL CO~ SUCURSAL DE~ Inact~ VAN  AD~  133761
##  2 1.55e4 BLAISE ~   83414 COBRO ADMI~ SUCURSAL SA~ Inact~ BLAISE ~   42569
##  3 3.44e4 INDUSTR~    7808 COBRO ADMI~ SUCURSAL OF~ Inact~ INDUSTR~    4000
##  4 4.73e4 VANNUCC~  620534 COBRO ADMI~ SUCURSAL SA~ Inact~ VANNUCC~  313886
##  5 5.01e4 MARIA S~  506818 COBRO ADMI~ SUCURSAL LI~ Activo <NA>          NA
##  6 1.49e5 ROSARIO~    8240 COBRO ADMI~ SUCURSAL OF~ Inact~ <NA>          NA
##  7 4.70e5 SAM SAM~  526936 COBRO ADMI~ SUCURSAL PA~ Inact~ SAM SAM~  264303
##  8 6.11e5 MULLER ~  103397 DIFICIL CO~ SUCURSAL ES~ Inact~ MULLER ~   52546
##  9 7.76e5 RODRIGU~   63089 COBRO ADMI~ SUCURSAL GU~ Inact~ <NA>          NA
## 10 1.07e6 MARKS R~ 1451873 COBRO JUDI~ SUCURSAL SA~ Inact~ MARKS R~  799625
## # ... with 78,693 more rows, and 2 more variables: situacion.y <chr>,
## #   lugar.pago.y <chr>

Si queremos saber el tipo dato de cada variable:

glimpse(morosidad)
## Rows: 78,703
## Columns: 10
## $ id           <dbl> 0, 15452, 34382, 47329, 50075, 149005, 469611, 611086,...
## $ nombre.x     <chr> "VAN ADELBERGEN ISOLDA", "BLAISE BLAISE CHRISTOPHE", "...
## $ deuda17      <dbl> 265838, 83414, 7808, 620534, 506818, 8240, 526936, 103...
## $ situacion.x  <chr> "DIFICIL COBRO", "COBRO ADMINISTRATIVO", "COBRO ADMINI...
## $ lugar.pago.x <chr> "SUCURSAL DESAMPARADOS", "SUCURSAL SANTA CRUZ", "SUCUR...
## $ Estado       <chr> "Inactivo", "Inactivo", "Inactivo", "Inactivo", "Activ...
## $ nombre.y     <chr> "VAN  ADELBERGEN ISOLDA", "BLAISE BLAISE CHRISTOPHE", ...
## $ deuda16      <dbl> 133761, 42569, 4000, 313886, NA, NA, 264303, 52546, NA...
## $ situacion.y  <chr> "COBRO ADMINISTRATIVO", "COBRO ADMINISTRATIVO", "COBRO...
## $ lugar.pago.y <chr> "SUCURSAL DESAMPARADOS", "SUCURSAL SANTA CRUZ", "SUCUR...

Paquete dplyr

Uno de los paquetes que más funciona para manipular datos de forma fácil es dplyr. Este paquete tiene, entre otras, seis funciones para manipular datos: select(), filter(), arrange(),mutate(), summarize() Group_by. Veamos cómo se usa cada una de ellas.

select()

Select nos permite seleccionar columnas. La sintaxis sería: select(dataframe, col1, col2) conde col1, col2, se refiere a los nombres de las columnas que queramos seleccionar.

Por ejemplo, supongamos que queremos seleccionar únicamente las columnas de id y deuda:

select(morosidad, id, deuda17, deuda16)
## # A tibble: 78,703 x 3
##         id deuda17 deuda16
##      <dbl>   <dbl>   <dbl>
##  1       0  265838  133761
##  2   15452   83414   42569
##  3   34382    7808    4000
##  4   47329  620534  313886
##  5   50075  506818      NA
##  6  149005    8240      NA
##  7  469611  526936  264303
##  8  611086  103397   52546
##  9  776002   63089      NA
## 10 1070043 1451873  799625
## # ... with 78,693 more rows

También podemos seleccionar todas las columnas menos algunas, esto lo hacemos poniendo - antes del nombre de la columna que no queremos seleccionar. Por ejemplo, si queremos todas las columnas menos Estado:

select(morosidad, -Estado)
## # A tibble: 78,703 x 9
##        id nombre.x deuda17 situacion.x lugar.pago.x nombre.y deuda16 situacion.y
##     <dbl> <chr>      <dbl> <chr>       <chr>        <chr>      <dbl> <chr>      
##  1 0.     VAN ADE~  265838 DIFICIL CO~ SUCURSAL DE~ VAN  AD~  133761 COBRO ADMI~
##  2 1.55e4 BLAISE ~   83414 COBRO ADMI~ SUCURSAL SA~ BLAISE ~   42569 COBRO ADMI~
##  3 3.44e4 INDUSTR~    7808 COBRO ADMI~ SUCURSAL OF~ INDUSTR~    4000 COBRO ADMI~
##  4 4.73e4 VANNUCC~  620534 COBRO ADMI~ SUCURSAL SA~ VANNUCC~  313886 COBRO ADMI~
##  5 5.01e4 MARIA S~  506818 COBRO ADMI~ SUCURSAL LI~ <NA>          NA <NA>       
##  6 1.49e5 ROSARIO~    8240 COBRO ADMI~ SUCURSAL OF~ <NA>          NA <NA>       
##  7 4.70e5 SAM SAM~  526936 COBRO ADMI~ SUCURSAL PA~ SAM SAM~  264303 COBRO ADMI~
##  8 6.11e5 MULLER ~  103397 DIFICIL CO~ SUCURSAL ES~ MULLER ~   52546 DIFICIL CO~
##  9 7.76e5 RODRIGU~   63089 COBRO ADMI~ SUCURSAL GU~ <NA>          NA <NA>       
## 10 1.07e6 MARKS R~ 1451873 COBRO JUDI~ SUCURSAL SA~ MARKS R~  799625 COBRO JUDI~
## # ... with 78,693 more rows, and 1 more variable: lugar.pago.y <chr>

Si queremos seleccionar un rango de columnas por ejemplo de id a situacion usamos :.

select(morosidad, id:situacion.x)
## # A tibble: 78,703 x 4
##         id nombre.x                                  deuda17 situacion.x        
##      <dbl> <chr>                                       <dbl> <chr>              
##  1       0 VAN ADELBERGEN ISOLDA                      265838 DIFICIL COBRO      
##  2   15452 BLAISE BLAISE CHRISTOPHE                    83414 COBRO ADMINISTRATI~
##  3   34382 INDUSTRIAS ELECTRONICAS COSTARRICENSES SA    7808 COBRO ADMINISTRATI~
##  4   47329 VANNUCCI VANNUCCI ALBERTO                  620534 COBRO ADMINISTRATI~
##  5   50075 MARIA SELENIA CAYETANA CARVAJAL VENEGAS    506818 COBRO ADMINISTRATI~
##  6  149005 ROSARIO CONEJO FÑCRUZ MARY GUASCH C          8240 COBRO ADMINISTRATI~
##  7  469611 SAM SAM BRIAN WALTER HUBERT                526936 COBRO ADMINISTRATI~
##  8  611086 MULLER MULLER JEAN-CLAUDE                  103397 DIFICIL COBRO      
##  9  776002 RODRIGUEZ RODRIGUEZ VICTOR MANUEL           63089 COBRO ADMINISTRATI~
## 10 1070043 MARKS RUIZ HENRY JAMES                    1451873 COBRO JUDICIAL     
## # ... with 78,693 more rows

Si queremos guardar el resultado de esa función en un nuevo objeto. Por ejemplo, si nos interesa quedarnos únicamente con columnas que no estén repetidas. nos damos cuenta que la columna de nombre, lugar de pago y situación se repiten, entonces vamos a deseleccionar esas columnas y crear un nuevo objeto que se llame morosidad1.

morosidad1 <- select(morosidad, -nombre.y, -situacion.y, -lugar.pago.y)
glimpse(morosidad1)
## Rows: 78,703
## Columns: 7
## $ id           <dbl> 0, 15452, 34382, 47329, 50075, 149005, 469611, 611086,...
## $ nombre.x     <chr> "VAN ADELBERGEN ISOLDA", "BLAISE BLAISE CHRISTOPHE", "...
## $ deuda17      <dbl> 265838, 83414, 7808, 620534, 506818, 8240, 526936, 103...
## $ situacion.x  <chr> "DIFICIL COBRO", "COBRO ADMINISTRATIVO", "COBRO ADMINI...
## $ lugar.pago.x <chr> "SUCURSAL DESAMPARADOS", "SUCURSAL SANTA CRUZ", "SUCUR...
## $ Estado       <chr> "Inactivo", "Inactivo", "Inactivo", "Inactivo", "Activ...
## $ deuda16      <dbl> 133761, 42569, 4000, 313886, NA, NA, 264303, 52546, NA...

filter()

La función filter nos permite filtrar filas.

La sintaxis es simple: filter(base, condicion). Donde condición es la condión lógica por la que queremos filtrar datos. Para ello usamos operadores lógicos:

  • >: mayor que.
  • <: menor que.
  • >=: mayor o igual que.
  • <=: menor o igual que.
  • ==: igual que (se ponen dos signos de igual).
  • !=: diferente.
  • &: y.
  • |: o.
  • is.na(variable): filtra los valores en blanco de la variable seleccionada.
  • !is.na(variable): filtra los valores que no están en blanco de la variable.

Por ejemplo, si queremos filtrar solamente las deudas superiores a un millón:

filter(morosidad1, deuda17>1000000)
## # A tibble: 30,438 x 7
##         id nombre.x        deuda17 situacion.x   lugar.pago.x     Estado deuda16
##      <dbl> <chr>             <dbl> <chr>         <chr>            <chr>    <dbl>
##  1  1.07e6 MARKS RUIZ HEN~  1.45e6 COBRO JUDICI~ SUCURSAL SAN IS~ Inact~  799625
##  2  3.00e6 HERNANDEZ RODA~  2.16e6 COBRO ADMINI~ SUCURSAL DESAMP~ Inact~ 1212624
##  3  4.97e6 SUCES DE EDUAR~  1.77e7 COBRO ADMINI~ SUCURSAL OFICIN~ Inact~      NA
##  4  9.70e6 VERONICA ALVAR~  4.18e6 COBRO ADMINI~ SUCURSAL OFICIN~ Inact~ 2449550
##  5  1.00e7 ANIBAL HERRERA~  1.33e6 COBRO ADMINI~ SUCURSAL HEREDIA Inact~  690318
##  6  1.10e7 RINE BORBON LU~  1.77e6 COBRO JUDICI~ SUCURSAL OFICIN~ Inact~  911028
##  7  1.17e7 MOSSUTO FONTAN~  1.87e6 COBRO JUDICI~ SUCURSAL OFICIN~ Inact~  962402
##  8  1.19e7 PETER ALEXANDE~  1.28e6 COBRO JUDICI~ SUCURSAL SANTO ~ Inact~  739723
##  9  1.19e7 DAMIA DAMIA EM~  4.69e6 COBRO ADMINI~ SUCURSAL SANTA ~ Inact~      NA
## 10  1.19e7 SCHLICKER SCHI~  1.29e6 DIFICIL COBRO SUCURSAL OFICIN~ Inact~  665574
## # ... with 30,428 more rows

O las deudas que crecieron entre 2016 y 2017:

filter(morosidad1, deuda17>deuda16)
## # A tibble: 56,539 x 7
##         id nombre.x         deuda17 situacion.x   lugar.pago.x    Estado deuda16
##      <dbl> <chr>              <dbl> <chr>         <chr>           <chr>    <dbl>
##  1       0 VAN ADELBERGEN ~  265838 DIFICIL COBRO SUCURSAL DESAM~ Inact~  133761
##  2   15452 BLAISE BLAISE C~   83414 COBRO ADMINI~ SUCURSAL SANTA~ Inact~   42569
##  3   34382 INDUSTRIAS ELEC~    7808 COBRO ADMINI~ SUCURSAL OFICI~ Inact~    4000
##  4   47329 VANNUCCI VANNUC~  620534 COBRO ADMINI~ SUCURSAL SANTA~ Inact~  313886
##  5  469611 SAM SAM BRIAN W~  526936 COBRO ADMINI~ SUCURSAL PARRI~ Inact~  264303
##  6  611086 MULLER MULLER J~  103397 DIFICIL COBRO SUCURSAL ESPAR~ Inact~   52546
##  7 1070043 MARKS RUIZ HENR~ 1451873 COBRO JUDICI~ SUCURSAL SAN I~ Inact~  799625
##  8 2380627 PLATERO FRANCO ~  717483 COBRO JUDICI~ SUCURSAL SIQUI~ Inact~  416596
##  9 3000465 HERNANDEZ RODAS~ 2156724 COBRO ADMINI~ SUCURSAL DESAM~ Inact~ 1212624
## 10 9700486 VERONICA ALVARE~ 4177836 COBRO ADMINI~ SUCURSAL OFICI~ Inact~ 2449550
## # ... with 56,529 more rows

O solamente las deudas mayores a un millón y de díficil cobro:

filter(morosidad1, deuda17>1000000 & situacion.x=="DIFICIL COBRO")
## # A tibble: 9,482 x 7
##         id nombre.x         deuda17 situacion.x  lugar.pago.x     Estado deuda16
##      <dbl> <chr>              <dbl> <chr>        <chr>            <chr>    <dbl>
##  1  1.19e7 SCHLICKER SCHI~  1293144 DIFICIL COB~ SUCURSAL OFICIN~ Inact~  6.66e5
##  2  1.21e7 DIAZ PILOTO JU~ 22229809 DIFICIL COB~ SUCURSAL CIUDAD~ Inact~  2.11e7
##  3  1.23e7 BIRD BIRD GEOF~  1267763 DIFICIL COB~ SUCURSAL SANTA ~ Inact~  6.38e5
##  4  1.33e7 LEWKOWICZ LEWK~  2074144 DIFICIL COB~ SUCURSAL OFICIN~ Inact~  1.08e6
##  5  1.35e7 BUSTOS VALDERR~  3317977 DIFICIL COB~ SUCURSAL OFICIN~ Inact~  1.73e6
##  6  1.35e7 PEREZ GIMENEZ ~  1830254 DIFICIL COB~ SUCURSAL SANTO ~ Inact~  9.30e5
##  7  1.35e7 SEIDLER SEIDLE~  4838378 DIFICIL COB~ SUCURSAL OFICIN~ Inact~  2.50e6
##  8  1.40e7 WILKIN WILKIN ~  1188119 DIFICIL COB~ SUCURSAL ALAJUE~ Inact~  6.11e5
##  9  1.41e7 JANDREZ LOPEZ ~  4053836 DIFICIL COB~ SUCURSAL PUNTAR~ Inact~  2.08e6
## 10  1.41e7 CETROLA CETROL~  1072692 DIFICIL COB~ SUCURSAL JACO    Inact~  5.34e5
## # ... with 9,472 more rows

En este ejemplo, tenemos deudas del 2016 y del 2017, y supongamos que nos interesa analizar únicamente los casos de las empresas o personas que han estado morosas por los dos años. Para ello, podemos usar la función filter:

morosidad1 <- filter(morosidad1, !is.na(deuda17), !is.na(deuda16))
morosidad1
## # A tibble: 58,990 x 7
##         id nombre.x         deuda17 situacion.x   lugar.pago.x    Estado deuda16
##      <dbl> <chr>              <dbl> <chr>         <chr>           <chr>    <dbl>
##  1       0 VAN ADELBERGEN ~  265838 DIFICIL COBRO SUCURSAL DESAM~ Inact~  133761
##  2   15452 BLAISE BLAISE C~   83414 COBRO ADMINI~ SUCURSAL SANTA~ Inact~   42569
##  3   34382 INDUSTRIAS ELEC~    7808 COBRO ADMINI~ SUCURSAL OFICI~ Inact~    4000
##  4   47329 VANNUCCI VANNUC~  620534 COBRO ADMINI~ SUCURSAL SANTA~ Inact~  313886
##  5  469611 SAM SAM BRIAN W~  526936 COBRO ADMINI~ SUCURSAL PARRI~ Inact~  264303
##  6  611086 MULLER MULLER J~  103397 DIFICIL COBRO SUCURSAL ESPAR~ Inact~   52546
##  7 1070043 MARKS RUIZ HENR~ 1451873 COBRO JUDICI~ SUCURSAL SAN I~ Inact~  799625
##  8 2380627 PLATERO FRANCO ~  717483 COBRO JUDICI~ SUCURSAL SIQUI~ Inact~  416596
##  9 3000465 HERNANDEZ RODAS~ 2156724 COBRO ADMINI~ SUCURSAL DESAM~ Inact~ 1212624
## 10 9700486 VERONICA ALVARE~ 4177836 COBRO ADMINI~ SUCURSAL OFICI~ Inact~ 2449550
## # ... with 58,980 more rows

El código de arriba lo que hace es filtrar la base por todos aquellos registros que no tengan valores vacíos en 2017 y luego por todos los que no tienen registros vacíos en 2016.

mutate()

Mutate nos permite crear nuevas columnas de forma fácil.

Podemos crear una variable que me diga cuánto cambió la deuda, que es la diferencia entre deuda17 y deuda16:

morosidad1 <-select(morosidad1,nombre.x,deuda16,deuda17)  # base reducida
 
morosidad1 <- mutate(morosidad1, cambio.deuda=deuda17-deuda16)
morosidad1
## # A tibble: 58,990 x 4
##    nombre.x                                  deuda16 deuda17 cambio.deuda
##    <chr>                                       <dbl>   <dbl>        <dbl>
##  1 VAN ADELBERGEN ISOLDA                      133761  265838       132077
##  2 BLAISE BLAISE CHRISTOPHE                    42569   83414        40845
##  3 INDUSTRIAS ELECTRONICAS COSTARRICENSES SA    4000    7808         3808
##  4 VANNUCCI VANNUCCI ALBERTO                  313886  620534       306648
##  5 SAM SAM BRIAN WALTER HUBERT                264303  526936       262633
##  6 MULLER MULLER JEAN-CLAUDE                   52546  103397        50851
##  7 MARKS RUIZ HENRY JAMES                     799625 1451873       652248
##  8 PLATERO FRANCO MARVIN                      416596  717483       300887
##  9 HERNANDEZ RODAS MANUEL ANTONIO            1212624 2156724       944100
## 10 VERONICA ALVAREZ ZAMORAN                  2449550 4177836      1728286
## # ... with 58,980 more rows

Ahora podemos crear una nueva variable que me categorice el cambio en la deuda en si aumentó o no. Esto podemos hacerlo con la función if_else() o ifelse (funciona igual). La sintaxis es: ifelse(condición, valor cierto, valor falso). (Es similar a la función if en Excel).

morosidad1 <- mutate(morosidad1, tipo.cambio=ifelse(cambio.deuda<0,"disminuyó", "aumentó"))
morosidad1
## # A tibble: 58,990 x 5
##    nombre.x                             deuda16 deuda17 cambio.deuda tipo.cambio
##    <chr>                                  <dbl>   <dbl>        <dbl> <chr>      
##  1 VAN ADELBERGEN ISOLDA                 133761  265838       132077 aumentó    
##  2 BLAISE BLAISE CHRISTOPHE               42569   83414        40845 aumentó    
##  3 INDUSTRIAS ELECTRONICAS COSTARRICEN~    4000    7808         3808 aumentó    
##  4 VANNUCCI VANNUCCI ALBERTO             313886  620534       306648 aumentó    
##  5 SAM SAM BRIAN WALTER HUBERT           264303  526936       262633 aumentó    
##  6 MULLER MULLER JEAN-CLAUDE              52546  103397        50851 aumentó    
##  7 MARKS RUIZ HENRY JAMES                799625 1451873       652248 aumentó    
##  8 PLATERO FRANCO MARVIN                 416596  717483       300887 aumentó    
##  9 HERNANDEZ RODAS MANUEL ANTONIO       1212624 2156724       944100 aumentó    
## 10 VERONICA ALVAREZ ZAMORAN             2449550 4177836      1728286 aumentó    
## # ... with 58,980 more rows

Con mutate podemos crear multiples variables a la vez, separando cada una por coma, por ejemplo:

morosidad1 <- mutate(morosidad1, cambio.deuda=deuda17-deuda16,
                     tipo.cambio=ifelse(cambio.deuda<0,"disminuyó", "aumentó"))
morosidad1
## # A tibble: 58,990 x 5
##    nombre.x                             deuda16 deuda17 cambio.deuda tipo.cambio
##    <chr>                                  <dbl>   <dbl>        <dbl> <chr>      
##  1 VAN ADELBERGEN ISOLDA                 133761  265838       132077 aumentó    
##  2 BLAISE BLAISE CHRISTOPHE               42569   83414        40845 aumentó    
##  3 INDUSTRIAS ELECTRONICAS COSTARRICEN~    4000    7808         3808 aumentó    
##  4 VANNUCCI VANNUCCI ALBERTO             313886  620534       306648 aumentó    
##  5 SAM SAM BRIAN WALTER HUBERT           264303  526936       262633 aumentó    
##  6 MULLER MULLER JEAN-CLAUDE              52546  103397        50851 aumentó    
##  7 MARKS RUIZ HENRY JAMES                799625 1451873       652248 aumentó    
##  8 PLATERO FRANCO MARVIN                 416596  717483       300887 aumentó    
##  9 HERNANDEZ RODAS MANUEL ANTONIO       1212624 2156724       944100 aumentó    
## 10 VERONICA ALVAREZ ZAMORAN             2449550 4177836      1728286 aumentó    
## # ... with 58,980 more rows

Arrange()

Arrange nos permite ordenar las base por una o varias columnas.

Por ejemplo, queremos ordenar la base en orden ascendente por deuda17 y por cambio.deuda:

morosidad1 <- arrange(morosidad1, deuda17, cambio.deuda)

Si lo queremos en orden descendente usamos desc()

morosidad1 <- arrange(morosidad1, desc(deuda17), desc(cambio.deuda))
Simplificar el trabajo: %>%

Un operador muy útil cuando trabajamos con ** dplyr** es el operador que visualmente se ve así %>%.

Lo primero es poner el objeto (tabla o dataframe) al cual queremos aplicar las operaciones de la forma base %>% funcion(). Esto nos ahorra estar poniendo como primer argumento de las funciones de dplyr al objeto.

Por ejemplo, recapitulemos todas las líneas de código que usamos anteriormente para limpiar la base de datos:

morosidad1 <- filter(morosidad1, !is.na(deuda17), !is.na(deuda16))
morosidad1 <- mutate(morosidad1, cambio.deuda=deuda17-deuda16)
morosidad1 <- mutate(morosidad1, tipo.cambio=ifelse(cambio.deuda<0,"disminuyó", "aumentó"))
morosidad1 <- arrange(morosidad1, desc(deuda17), desc(cambio.deuda))

Todos los pasos realizados anteriormente podríamos haberlos hecho de forma más simple usando el %>%:

morosidad2 <- morosidad1 %>%
  filter(!is.na(deuda17), !is.na(deuda16)) %>%
  mutate(cambio.deuda=deuda17-deuda16,
       tipo.cambio=ifelse(cambio.deuda<0,"disminuyó", "aumentó")) %>%
  arrange(desc(deuda17), desc(cambio.deuda))
morosidad2
## # A tibble: 58,990 x 5
##    nombre.x                            deuda16  deuda17 cambio.deuda tipo.cambio
##    <chr>                                 <dbl>    <dbl>        <dbl> <chr>      
##  1 CONFECCIONES BOR KAR SOCIEDAD AN~    1.62e9   2.28e9    664145284 aumentó    
##  2 DATASCENSION INC S.A.                1.16e9   1.66e9    501205866 aumentó    
##  3 POLY PLASTICOS SOCIEDAD ANONIMA      3.61e8   1.06e9    702365880 aumentó    
##  4 DESARROLLOS CONSTRUCCION E INGEN~    6.04e8   9.03e8    299484834 aumentó    
##  5 T A T F SOCIEDAD ANONIMA             5.48e8   8.51e8    303027135 aumentó    
##  6 VIALINX SOCIEDAD ANONIMA             3.00e8   8.36e8    536263351 aumentó    
##  7 ASOCIACION DE PEQUEÑOS AGRICULTO~    4.23e8   7.54e8    331069601 aumentó    
##  8 COLEGIOS SUPERIORES DE COSTA RIC~    5.78e8   7.16e8    138476162 aumentó    
##  9 HELECHOS EXPRESO SOCIEDAD ANONIMA    4.12e8   6.80e8    268389951 aumentó    
## 10 MIL NOVECIENTOS SESENTA Y SIETE ~    3.98e8   6.59e8    261240005 aumentó    
## # ... with 58,980 more rows

summarise()

Summarise funciona de forma análoga a mutate, excepto que en lugar de añadir nuevas columnas crea un nuevo data frame.

morosidad1 <-morosidad %>% 
  select(situacion.x,deuda17,deuda16)  %>% 
  filter(!is.na(deuda17), !is.na(deuda16)) %>% 
  mutate(cambio.deuda=deuda17-deuda16) # base reducida


morosidad1 %>% 
summarise(promedio = mean(cambio.deuda), Desviacion = sd(cambio.deuda))
## # A tibble: 1 x 2
##   promedio Desviacion
##      <dbl>      <dbl>
## 1 1969246.  10026623.

Group_by()

Group by es uno de los comandos más útiles. Como su nombre lo dice nos permite agrupar variables y hacer cálculos entre los grupos, por ejemplo calcular nuevas variables o estadísticos para los grupos.

Por ejemplo, si queremos crear una nueva variable cuyo valor sea la diferencia de deuda promedio de cada situación. En este caso podemos hacer uso de group_by.

morosidad1  %>% 
group_by(situacion.x)   %>% 
summarise(promedio.cambio.deuda = mean(cambio.deuda))
## # A tibble: 3 x 2
##   situacion.x          promedio.cambio.deuda
## * <chr>                                <dbl>
## 1 COBRO ADMINISTRATIVO               448823.
## 2 COBRO JUDICIAL                    2200479.
## 3 DIFICIL COBRO                     2379985.