Semana_06_practica

🎯 Objetivo: Limpiar completamente un dataset con problemas reales y construir un resumen analítico usando dplyr.

Author

Adrian Rafael Guigni Guillen

- Librerías

Code
library(tidyverse)  
library(stringr) 
library(dplyr) 
library(kableExtra)

- Dataset

Code
ventas_crudas <- tibble(
  id_venta    = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 3),
  vendedor    = c("ana", "PEDRO", "María ", NA, "carmen", "ana", "PEDRO", "luis", "carmen", "luis", "María "),
  region      = c("norte", "SUR", "Norte", "sur", "NORTE", "norte", "sur", "Norte", "sur", "norte", "Norte"),
  monto       = c(15000, 22000, 18500, NA, 31000, 16000, 19500, 9500000, 21000, 17500, 18500),
  mes         = c(1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 1),
  completada  = c("SI", "SI", "NO", "SI", NA, "SI", "NO", "SI", "SI", "NO", "NO")
)
Ventas crudas
id_venta vendedor region monto mes completada
1 ana norte 15000 1 SI
2 PEDRO SUR 22000 1 SI
3 María Norte 18500 1 NO
4 NA sur NA 2 SI
5 carmen NORTE 31000 2 NA
6 ana norte 16000 2 SI
7 PEDRO sur 19500 3 NO
8 luis Norte 9500000 3 SI
9 carmen sur 21000 3 SI
10 luis norte 17500 3 NO
3 María Norte 18500 1 NO

1 - Diagnóstico inicial:

Code
# 1.1 - Usar glimpse() para para entender el estado del dataset
glimpse(ventas_crudas)
Rows: 11
Columns: 6
$ id_venta   <dbl> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 3
$ vendedor   <chr> "ana", "PEDRO", "María ", NA, "carmen", "ana", "PEDRO", "lu…
$ region     <chr> "norte", "SUR", "Norte", "sur", "NORTE", "norte", "sur", "N…
$ monto      <dbl> 15000, 22000, 18500, NA, 31000, 16000, 19500, 9500000, 2100…
$ mes        <dbl> 1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 1
$ completada <chr> "SI", "SI", "NO", "SI", NA, "SI", "NO", "SI", "SI", "NO", "…
Code
# 1.2 - Usar summary() para para entender el estado del dataset
summary(ventas_crudas)
    id_venta           vendedor        region       monto              mes   
 Min.   : 1.000   Length   :11   Length   :11   Min.   :  15000   Min.   :1  
 1st Qu.: 3.000   N.unique : 5   N.unique : 5   1st Qu.:  17750   1st Qu.:1  
 Median : 5.000   N.blank  : 0   N.blank  : 0   Median :  19000   Median :2  
 Mean   : 5.273   Min.nchar: 3   Min.nchar: 3   Mean   : 967900   Mean   :2  
 3rd Qu.: 7.500   Max.nchar: 6   Max.nchar: 5   3rd Qu.:  21750   3rd Qu.:3  
 Max.   :10.000   NAs      : 1                  Max.   :9500000   Max.   :3  
                                                NAs    :1                    
     completada
 Length   :11  
 N.unique : 2  
 N.blank  : 0  
 Min.nchar: 2  
 Max.nchar: 2  
 NAs      : 1  
               
Code
# 1.3 - Usar colSums(is.na()) para para entender el estado del dataset
colSums(is.na(ventas_crudas)) # <- Para saber donde hay NA
  id_venta   vendedor     region      monto        mes completada 
         0          1          0          1          0          1 

1.4 - Identificar en comentarios:

¿Cuántos duplicados hay? Hay un duplicado en id_venta, el 3 esta 2 veces.

¿Cuántos NAs por columna? Las columnas “vendedor”, “monto” y “completada” tienen 1 NA.

¿Hay outliers? Si, en la columna “monto” el valor “9500000” esta fuera del rango de los demas valores.

2 — Limpieza:

Code
ventas_limpias <- ventas_crudas |>
  
# 2.1 - Quitar duplicados por id_venta:
  
distinct(id_venta, .keep_all = TRUE) |>

# 2.2 y 2.4 - Limpiar vendedor y region / Imputar el NA de vendedor con "Desconocido" 

mutate(
  vendedor  = str_trim(str_to_title(vendedor)) |> 
    replace_na("Desconocido"),
  
  region  = str_to_lower(str_trim(region))
) |> 

# 2.3 - Imputar el NA de monto con la mediana del mes correspondiente:
  
group_by(mes) |> 
  mutate(monto = if_else(is.na(monto), median(monto, na.rm = TRUE), monto)) |>
  ungroup() |>
  
# 2.5 - Convertir completada a factor con replace_na() aplicando "NO" a los NAs
mutate(
  completada = replace_na(completada,"NO"),
  completada = factor(completada, levels = c("SI","NO"))
  )

# 2.6 - Marcar el outlier en monto con una columna booleana es_outlier usando IQR

Q1  <- quantile(ventas_limpias$monto, 0.25, na.rm = TRUE)
Q3  <- quantile(ventas_limpias$monto, 0.75, na.rm = TRUE)
iqr <- IQR(ventas_limpias$monto, na.rm = TRUE)

limite_inferior <- Q1 - 1.5 * iqr
limite_superior <- Q3 + 1.5 * iqr #si se pasa de alguno de los dos, es outlier.

ventas_limpias <- ventas_limpias |>
  mutate(es_outlier = monto < limite_inferior | monto > limite_superior) # <- Columna booleana, nota "|" es el operador logico or. 
Ventas limpias
id_venta vendedor region monto mes completada es_outlier
1 Ana norte 15000 1 SI FALSE
2 Pedro sur 22000 1 SI FALSE
3 María norte 18500 1 NO FALSE
4 Desconocido sur 23500 2 SI FALSE
5 Carmen norte 31000 2 NO FALSE
6 Ana norte 16000 2 SI FALSE
7 Pedro sur 19500 3 NO FALSE
8 Luis norte 9500000 3 SI TRUE
9 Carmen sur 21000 3 SI FALSE
10 Luis norte 17500 3 NO FALSE

3 - Transformación con dplyr:

Code
# 3.1 - Crear columna comision = 5% del monto si completada == "SI", 0 si no 
ventas_limpias <- ventas_limpias |> 
mutate(
  comision = if_else (completada == 'SI', monto * 0.05, 0)
)
Code
# 3.2 - Crear columna categoria_venta con case_when(): Baja (<15000), Media (15000-25000), Alta (>25000)
ventas_limpias <- ventas_limpias |> 
  mutate(
    categoria_venta = case_when(
        monto < 15000              ~ "Baja",
        monto >= 15000 & monto < 25000 ~ "Media",
        monto >= 25000  ~ "Alta")
  )
Code
# 3.3 - Calcular ranking de vendedor por monto usando rank(desc(monto)) dentro de cada region
ventas_limpias <- ventas_limpias |>
  group_by(region) |>
  mutate(
    ranking = rank(desc(monto))
  ) |>
  ungroup()
Ventas limpias (dplyr)
id_venta vendedor region monto mes completada es_outlier comision categoria_venta ranking
1 Ana norte 15000 1 SI FALSE 750 Media 6
2 Pedro sur 22000 1 SI FALSE 1100 Media 2
3 María norte 18500 1 NO FALSE 0 Media 3
4 Desconocido sur 23500 2 SI FALSE 1175 Media 1
5 Carmen norte 31000 2 NO FALSE 0 Alta 2
6 Ana norte 16000 2 SI FALSE 800 Media 5
7 Pedro sur 19500 3 NO FALSE 0 Media 4
8 Luis norte 9500000 3 SI TRUE 475000 Alta 1
9 Carmen sur 21000 3 SI FALSE 1050 Media 3
10 Luis norte 17500 3 NO FALSE 0 Media 4

4 - Resumen analítico:

Code
# 4.1 - Usando `group_by()` + `summarise()` construye una tabla que muestre por `vendedor`:

#- Total de ventas completadas
#- Monto total vendido
#- Monto promedio por venta
#- Comisión total ganada
#- Ordenada de mayor a menor monto total

resumen <- ventas_limpias |> 
  group_by(vendedor) |> 
  summarise(
    total_ventas_completadas = sum (completada == 'SI'),
    monto_total = sum(monto),
    monto_promedio = mean(monto),
    comision_total = sum(comision)
  ) |>
   arrange(desc(monto_total))
Resumen analítico
vendedor total_ventas_completadas monto_total monto_promedio comision_total
Luis 1 9517500 4758750 475000
Carmen 1 52000 26000 1050
Pedro 1 41500 20750 1100
Ana 2 31000 15500 1550
Desconocido 1 23500 23500 1175
María 0 18500 18500 0