\[ \]
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:
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.
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...
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 muestraprop.t=T
: porcentaje total de la tabla. Si lo ponemos = F no lo muestraPara 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
## --------------------------------------------------------------------------------
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...
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 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...
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 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 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))
%>%
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 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 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.