Limpieza y procesamiento

1 Introducción

LinkedIn GitHub Twitter

Este archivo pretende ser una pequeña guía rápida sobre limpieza de data y procesamiento de información, la cual se encontrará en constante actualización. Si cuenta con alguna duda, no dude en escribirme a alguna de mis redes dándole click a los íconos.

2 Carga de datos

2.1 Desde github

library(rio)
data_git = import("https://raw.githubusercontent.com/alfredoaroterleira/data/refs/heads/main/data_ejemplo.csv")  #puede ser xlsx
head(data_git)
##   Ubigeo Departamento        Provincia      Distrito Personas Monto Categoria
## 1 150122         Lima             Lima    Miraflores       12  12,4         1
## 2  80110        Cusco            Cusco San Sebastián       54  23,5         2
## 3  40115     Arequipa         Arequipa    Paucarpata       34 12,56         4
## 4  60101    Cajamarca        Cajamarca     Cajamarca       45 17,87         6
## 5 250104      Ucayali Coronel Portillo   Yarinacocha       47 87,65         2
## 6 220901   San Martín       San Martín      Tarapoto       67 23,23         4
##   Categoria_ord Logica
## 1       Inicial      0
## 2    Secundaria      1
## 3      Superior      1
## 4       Inicial      1
## 5    Secundaria      0
## 6       Inicial      0

2.2 Desde hojas de cálculo - google

link = 'https://docs.google.com/spreadsheets/d/e/2PACX-1vRwpfchMwZa_GajZ_k0eG3wKDRuKM95M7EU9I48pA1WIWZjAT5fKBtNWvoM1rFIJADV6282Vq0SaWFH/pub?gid=0&single=true&output=csv'

data_google = read.csv(link)
head(data_google)
##   Ubigeo Departamento        Provincia      Distrito Personas Monto Categoria
## 1 150122         Lima             Lima    Miraflores       12  12,4         1
## 2  80110        Cusco            Cusco San Sebastián       54  23,5         2
## 3  40115     Arequipa         Arequipa    Paucarpata       34 12,56         4
## 4  60101    Cajamarca        Cajamarca     Cajamarca       45 17,87         6
## 5 250104      Ucayali Coronel Portillo   Yarinacocha       47 87,65         2
## 6 220901   San Martín       San Martín      Tarapoto       67 23,23         4
##   Categoria_ord Logica
## 1       Inicial      0
## 2    Secundaria      1
## 3      Superior      1
## 4       Inicial      1
## 5    Secundaria      0
## 6       Inicial      0

2.3 Empleando rio

library(rio)
data_rio = import("data_ejemplo.csv")
head(data_rio)
##   Ubigeo Departamento        Provincia      Distrito Personas Monto Categoria
## 1 150122         Lima             Lima    Miraflores       12  12,4         1
## 2  80110        Cusco            Cusco San Sebastián       54  23,5         2
## 3  40115     Arequipa         Arequipa    Paucarpata       34 12,56         4
## 4  60101    Cajamarca        Cajamarca     Cajamarca       45 17,87         6
## 5 250104      Ucayali Coronel Portillo   Yarinacocha       47 87,65         2
## 6 220901   San Martín       San Martín      Tarapoto       67 23,23         4
##   Categoria_ord Logica
## 1       Inicial      0
## 2    Secundaria      1
## 3      Superior      1
## 4       Inicial      1
## 5    Secundaria      0
## 6       Inicial      0

3 Inspección y diagnóstico

3.1 Empleando str

str(data_git)
## 'data.frame':    20 obs. of  9 variables:
##  $ Ubigeo       : int  150122 80110 40115 60101 250104 220901 50101 220101 170101 210101 ...
##  $ Departamento : chr  "Lima" "Cusco" "Arequipa" "Cajamarca" ...
##  $ Provincia    : chr  "Lima" "Cusco" "Arequipa" "Cajamarca" ...
##  $ Distrito     : chr  "Miraflores" "San Sebastián" "Paucarpata" "Cajamarca" ...
##  $ Personas     : int  12 54 34 45 47 67 98 31 54 45 ...
##  $ Monto        : chr  "12,4" "23,5" "12,56" "17,87" ...
##  $ Categoria    : int  1 2 4 6 2 4 5 1 3 3 ...
##  $ Categoria_ord: chr  "Inicial" "Secundaria" "Superior" "Inicial" ...
##  $ Logica       : int  0 1 1 1 0 0 1 0 NA 0 ...

3.2 Contamos filas y columnas

dim(data_git)
## [1] 20  9

3.3 Las variables de mi data

names(data_git)
## [1] "Ubigeo"        "Departamento"  "Provincia"     "Distrito"     
## [5] "Personas"      "Monto"         "Categoria"     "Categoria_ord"
## [9] "Logica"

3.4 Tipos de datos de cada columna

library(dplyr)
glimpse(data_git)
## Rows: 20
## Columns: 9
## $ Ubigeo        <int> 150122, 80110, 40115, 60101, 250104, 220901, 50101, 2201…
## $ Departamento  <chr> "Lima", "Cusco", "Arequipa", "Cajamarca", "Ucayali", "Sa…
## $ Provincia     <chr> "Lima", "Cusco", "Arequipa", "Cajamarca", "Coronel Porti…
## $ Distrito      <chr> "Miraflores", "San Sebastián", "Paucarpata", "Cajamarca"…
## $ Personas      <int> 12, 54, 34, 45, 47, 67, 98, 31, 54, 45, 63, 79, 45, 12, …
## $ Monto         <chr> "12,4", "23,5", "12,56", "17,87", "87,65", "23,23", "45,…
## $ Categoria     <int> 1, 2, 4, 6, 2, 4, 5, 1, 3, 3, 4, 6, 6, 5, 2, 3, 1, 4, 5,…
## $ Categoria_ord <chr> "Inicial", "Secundaria", "Superior", "Inicial", "Secunda…
## $ Logica        <int> 0, 1, 1, 1, 0, 0, 1, 0, NA, 0, 1, 1, 0, NA, 0, 1, 0, 0, …

4 Limpieza de datos

4.1 Eliminar todas las filas con NA’s

data_rio = data_rio[complete.cases(data_rio), ]

4.2 Eliminar filas con NA solo en una columna específica

data_google = data_google[!is.na(data_google$Logica), ]

4.3 Modificar NA’s (rellenarlos/imputarlos)

4.3.1 Variables numéricas (edad, ingreso, cantidad)

#MEDIA: si los datos son simétricos y sin muchos outliers
data_git$Personas[is.na(data_git$Personas)] <- mean(data_git$Personas, na.rm = TRUE)
#MEDIANA: si hay muchos outliers
data_git$Personas[is.na(data_git$Personas)] <- median(data_git$Personas, na.rm = TRUE)
#CERO: 0 si tiene un significado válido
data_git$Personas[is.na(data_git$Personas)] <- 0

4.3.2 Variables categóricas (sexo, región, nivel educativo)

#MODA: categoría más frecuente
moda <- names(sort(table(data_git$Categoria_ord), decreasing = TRUE))[1]
data_git$Categoria_ord[is.na(data_git$Categoria_ord)] <- moda
#Artificial: no especificado
data_git$Categoria_ord[is.na(data_git$Categoria_ord)] <- "No especificado"

5 Transformación de variables

5.1 Transformación unitaria

data_git$Personas = as.numeric(data_git$Personas)

#as.factor, as.character, as.integer, ....

5.1.1 Variable categórica ordenada

Si fuese una variable categórica ordenada

niveles <- c("Inicial", "Primaria", "Secundaria", "Superior")
data_git$Categoria_ord <- as.ordered(factor(data_git$Categoria_ord, levels = niveles))

5.2 Transformación grupal

library(dplyr)

data_git <- data_git %>%
  mutate(across(c(Departamento, Provincia, Distrito), as.character))

Si las variables tendrían un patrón común en el nombre:

# data <-  data %>%
#   mutate(across(starts_with("ingreso_"),as.numeric))

6 Edición de data

6.1 Nombres en mayúsculas y sin tildes

library(stringi)

data_git$Departamento <- toupper(stri_trans_general(data_git$Departamento, "Latin-ASCII"))

6.2 Coma por punto

data_git$Monto <- as.numeric(gsub(",",".",data_git$Monto))

#si el número es el siguiente 21,234.67 el código debe ser el siguiente: data$variable <- gsub(",","",data$variable)

#de esa forma se eliminan las comas como separador de miles

7 Selección

7.1 Selección de variables

library(dplyr)

#seleccionando
data_final <- data_git %>%
  select(Departamento, Provincia, Distrito)

7.2 Eliminación de variables

library(dplyr)

#eliminando
data_final2 <- data_google %>%
  select(-c(Departamento, Provincia, Distrito))

7.3 Selección bajo filtro

library(dplyr)

subdata <- data_rio %>%
  filter(Provincia == "Lima")
#solo algunas columnas

library(dplyr)

subdata2 <- data_google %>%
  filter(Provincia == "Lima") %>%
  select(Personas, Ubigeo, Distrito)

8 Cambiar nombre de columnas

library(dplyr)

data_edit <- data_git %>%
  rename(
    PROVINCIA = Provincia,
    CATEGORIA = Categoria
  )

names(data_edit)
## [1] "Ubigeo"        "Departamento"  "PROVINCIA"     "Distrito"     
## [5] "Personas"      "Monto"         "CATEGORIA"     "Categoria_ord"
## [9] "Logica"

9 Integración o unión de bases de datos

9.1 Merge por columna compartida

library(dplyr)

data_merge1 <- inner_join(data_git, data_google, by = "Provincia")  #inner_join solo las coincidentes, full_join incluyendo todas las filas, aunque solo estén en una data
head(data_merge1)
##   Ubigeo.x Departamento.x        Provincia    Distrito.x Personas.x Monto.x
## 1   150122           LIMA             Lima    Miraflores         12   12.40
## 2   150122           LIMA             Lima    Miraflores         12   12.40
## 3    80110          CUSCO            Cusco San Sebastián         54   23.50
## 4    40115       AREQUIPA         Arequipa    Paucarpata         34   12.56
## 5    60101      CAJAMARCA        Cajamarca     Cajamarca         45   17.87
## 6   250104        UCAYALI Coronel Portillo   Yarinacocha         47   87.65
##   Categoria.x Categoria_ord.x Logica.x Ubigeo.y Departamento.y    Distrito.y
## 1           1         Inicial        0   150122           Lima    Miraflores
## 2           1         Inicial        0   150144           Lima   Santa Anita
## 3           2      Secundaria        1    80110          Cusco San Sebastián
## 4           4        Superior        1    40115       Arequipa    Paucarpata
## 5           6         Inicial        1    60101      Cajamarca     Cajamarca
## 6           2      Secundaria        0   250104        Ucayali   Yarinacocha
##   Personas.y Monto.y Categoria.y Categoria_ord.y Logica.y
## 1         12    12,4           1         Inicial        0
## 2         64   95,59           1        Primaria        0
## 3         54    23,5           2      Secundaria        1
## 4         34   12,56           4        Superior        1
## 5         45   17,87           6         Inicial        1
## 6         47   87,65           2      Secundaria        0
library(dplyr)

data_mergeleft <- left_join(data_final, data_git, by = "Provincia")  #uso la data 1 como base, right_join uso la derecha
head(data_mergeleft)
##   Departamento.x        Provincia    Distrito.x Ubigeo Departamento.y
## 1           LIMA             Lima    Miraflores 150122           LIMA
## 2           LIMA             Lima    Miraflores 150144           LIMA
## 3          CUSCO            Cusco San Sebastián  80110          CUSCO
## 4       AREQUIPA         Arequipa    Paucarpata  40115       AREQUIPA
## 5      CAJAMARCA        Cajamarca     Cajamarca  60101      CAJAMARCA
## 6        UCAYALI Coronel Portillo   Yarinacocha 250104        UCAYALI
##      Distrito.y Personas Monto Categoria Categoria_ord Logica
## 1    Miraflores       12 12.40         1       Inicial      0
## 2   Santa Anita       64 95.59         1      Primaria      0
## 3 San Sebastián       54 23.50         2    Secundaria      1
## 4    Paucarpata       34 12.56         4      Superior      1
## 5     Cajamarca       45 17.87         6       Inicial      1
## 6   Yarinacocha       47 87.65         2    Secundaria      0

9.2 Merge de más de dos datas

library(dplyr)
library(purrr)

lista_datas <- list(data_final, data_git, data_google)
df_merged <- reduce(lista_datas, inner_join, by="Provincia") #full_join
names(df_merged)
##  [1] "Departamento.x"  "Provincia"       "Distrito.x"      "Ubigeo.x"       
##  [5] "Departamento.y"  "Distrito.y"      "Personas.x"      "Monto.x"        
##  [9] "Categoria.x"     "Categoria_ord.x" "Logica.x"        "Ubigeo.y"       
## [13] "Departamento"    "Distrito"        "Personas.y"      "Monto.y"        
## [17] "Categoria.y"     "Categoria_ord.y" "Logica.y"

10 Descarga de data creada

10.1 Descarga en diversos formatos

#write.csv(df_merged, "mi_data.csv", row.names = FALSE) #CSV
#library(writexl)
#write_xlsx(df_merged, "mi_data.xslx")