Semana06_rubi_pineda

Author

Rubi Pineda

Published

14 Jun 2026

Code
#| echo: true

library (tidyverse)
library(dplyr)

1 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
# A tibble: 11 × 6
   id_venta vendedor region   monto   mes completada
      <dbl> <chr>    <chr>    <dbl> <dbl> <chr>     
 1        1 "ana"    norte    15000     1 SI        
 2        2 "PEDRO"  SUR      22000     1 SI        
 3        3 "María " Norte    18500     1 NO        
 4        4  <NA>    sur         NA     2 SI        
 5        5 "carmen" NORTE    31000     2 <NA>      
 6        6 "ana"    norte    16000     2 SI        
 7        7 "PEDRO"  sur      19500     3 NO        
 8        8 "luis"   Norte  9500000     3 SI        
 9        9 "carmen" sur      21000     3 SI        
10       10 "luis"   norte    17500     3 NO        
11        3 "María " Norte    18500     1 NO        

2 Diagnóstico inicial

Code
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
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
colSums(is.na(ventas_crudas))
  id_venta   vendedor     region      monto        mes completada 
         0          1          0          1          0          1 
Note

Comentarios:

Code
# Hay 1 duplicado(s) en total
# Hay 1 NA por columna en "vendedor", "monto" y "completada", para un total de 3 NAs.
# Por ahora hay dos outliers: 31000 y 9500000 (el código se presentará a continuación), pero cuando reemplace NA en la columna "monto" por la mediana, solo habrá un outlier que naturalmente será el de 9500000.

2.1 Diagnostico con codigo

Para respaldar el diagnóstico, lo mostraré con codigo:

2.1.1 Nas

Code
colSums(is.na(ventas_crudas))
  id_venta   vendedor     region      monto        mes completada 
         0          1          0          1          0          1 

2.1.2 Duplicados

Code
sum(duplicated(ventas_crudas))
[1] 1

2.1.3 Outliers

Code
# Ver outliers con filter

ventas_outliers <- ventas_crudas |>
  filter(
    monto < quantile(monto, 0.25, na.rm = TRUE) - 1.5 * IQR(monto, na.rm = TRUE) |
    monto > quantile(monto, 0.75, na.rm = TRUE) + 1.5 * IQR(monto, na.rm = TRUE)
  )

ventas_outliers
# A tibble: 2 × 6
  id_venta vendedor region   monto   mes completada
     <dbl> <chr>    <chr>    <dbl> <dbl> <chr>     
1        5 carmen   NORTE    31000     2 <NA>      
2        8 luis     Norte  9500000     3 SI        

3 Limpieza

Code
# Eliminar filas duplicadas por id_venta
ventas_crudas <- ventas_crudas %>%
  filter(!duplicated(id_venta))

# Limpiar vendedor y region (trim + title case / lower case consistente)
ventas_crudas <- ventas_crudas %>% mutate(
    vendedor = str_trim (str_to_title(vendedor)),
    region = str_to_lower(str_trim(region))
  )

#Imputar el NA de `monto` con la mediana del mes correspondiente

Mediana <- ventas_crudas  %>% 
  filter(mes == 2)  %>% 
  summarise(mediana = median(monto, na.rm = TRUE))

ventas_crudas <- ventas_crudas %>%
  mutate (monto = if_else(is.na(monto), Mediana$mediana, monto))


#Imputar el NA de `vendedor` con `"Desconocido"`

ventas_crudas <- ventas_crudas %>%
  mutate (vendedor = if_else(is.na(vendedor), "Desconocido", vendedor))


#Convertir completada a factor con replace_na() aplicando "NO" a los NAs

ventas_crudas <- ventas_crudas %>%
  mutate(
    completada = replace_na(completada, "NO"),
    completada = factor(completada, levels = c("NO", "SI"))
  )

glimpse(ventas_crudas$completada)
 Factor w/ 2 levels "NO","SI": 2 2 1 2 1 2 1 2 2 1
Code
ventas_crudas
# A tibble: 10 × 6
   id_venta vendedor    region   monto   mes completada
      <dbl> <chr>       <chr>    <dbl> <dbl> <fct>     
 1        1 Ana         norte    15000     1 SI        
 2        2 Pedro       sur      22000     1 SI        
 3        3 María       norte    18500     1 NO        
 4        4 Desconocido sur      23500     2 SI        
 5        5 Carmen      norte    31000     2 NO        
 6        6 Ana         norte    16000     2 SI        
 7        7 Pedro       sur      19500     3 NO        
 8        8 Luis        norte  9500000     3 SI        
 9        9 Carmen      sur      21000     3 SI        
10       10 Luis        norte    17500     3 NO        
Code
#Marcar el outlier en monto con una columna booleana es_outlier usando IQR

limites <- ventas_crudas %>% 
  summarise(
    Q1 = quantile(monto, 0.25, na.rm = TRUE),
    Q3 = quantile(monto, 0.75, na.rm = TRUE)
    ) %>%
  mutate(IQR_val = Q3 - Q1,
         limite_inferior = Q1 - 1.5 * IQR_val,
         limite_superior = Q3 + 1.5 * IQR_val)

ventas_crudas <- ventas_crudas %>% 
  mutate(es_outlier = monto > limites$limite_superior | monto < limites$limite_inferior)

ventas_crudas
# A tibble: 10 × 7
   id_venta vendedor    region   monto   mes completada es_outlier
      <dbl> <chr>       <chr>    <dbl> <dbl> <fct>      <lgl>     
 1        1 Ana         norte    15000     1 SI         FALSE     
 2        2 Pedro       sur      22000     1 SI         FALSE     
 3        3 María       norte    18500     1 NO         FALSE     
 4        4 Desconocido sur      23500     2 SI         FALSE     
 5        5 Carmen      norte    31000     2 NO         FALSE     
 6        6 Ana         norte    16000     2 SI         FALSE     
 7        7 Pedro       sur      19500     3 NO         FALSE     
 8        8 Luis        norte  9500000     3 SI         TRUE      
 9        9 Carmen      sur      21000     3 SI         FALSE     
10       10 Luis        norte    17500     3 NO         FALSE     

4 Transformación con dplyr

Code
# Crear columna comision

ventas_crudas <- ventas_crudas %>%
  mutate(comision = if_else(completada == "SI", monto * 0.05, 0))

    
# Crear columna categoria_venta con case_when

ventas_crudas <- ventas_crudas %>%
  mutate(categoria_venta = case_when(
      monto < 15000 ~ "Baja",
      monto >= 15000 & monto <= 25000 ~ "Media",
      monto > 25000 ~ "Alta",
      TRUE ~ "Sin clasificar"
    )
  )
    
glimpse(ventas_crudas)
Rows: 10
Columns: 9
$ id_venta        <dbl> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
$ vendedor        <chr> "Ana", "Pedro", "María", "Desconocido", "Carmen", "Ana…
$ region          <chr> "norte", "sur", "norte", "sur", "norte", "norte", "sur…
$ monto           <dbl> 15000, 22000, 18500, 23500, 31000, 16000, 19500, 95000…
$ mes             <dbl> 1, 1, 1, 2, 2, 2, 3, 3, 3, 3
$ completada      <fct> SI, SI, NO, SI, NO, SI, NO, SI, SI, NO
$ es_outlier      <lgl> FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE,…
$ comision        <dbl> 750, 1100, 0, 1175, 0, 800, 0, 475000, 1050, 0
$ categoria_venta <chr> "Media", "Media", "Media", "Media", "Alta", "Media", "…
Code
ventas_crudas
# A tibble: 10 × 9
   id_venta vendedor    region   monto   mes completada es_outlier comision
      <dbl> <chr>       <chr>    <dbl> <dbl> <fct>      <lgl>         <dbl>
 1        1 Ana         norte    15000     1 SI         FALSE           750
 2        2 Pedro       sur      22000     1 SI         FALSE          1100
 3        3 María       norte    18500     1 NO         FALSE             0
 4        4 Desconocido sur      23500     2 SI         FALSE          1175
 5        5 Carmen      norte    31000     2 NO         FALSE             0
 6        6 Ana         norte    16000     2 SI         FALSE           800
 7        7 Pedro       sur      19500     3 NO         FALSE             0
 8        8 Luis        norte  9500000     3 SI         TRUE         475000
 9        9 Carmen      sur      21000     3 SI         FALSE          1050
10       10 Luis        norte    17500     3 NO         FALSE             0
# ℹ 1 more variable: categoria_venta <chr>
Important

A partir de aquí filtraré en base a las ventas que “SI” fueron completadas, ya que si una venta no se llevó a cabo, el empleado no debería subir en el ranking por ella. Tampoco debería haber un monto que no se haya vendido en el “monto total” de sus ventas, porque entonces eso significaría que ese dinero realmente no se ganó y no sería una métrica en base a la realidad.

Code
#| echo: true

# Ranking de vendedor por monto dentro de cada región

Ranking <- ventas_crudas %>%
  filter(completada == "SI") %>%
  group_by(region, vendedor) %>%
  summarise(
    monto_total = sum(monto, na.rm = TRUE)) %>%
  mutate(
    ranking = rank(desc(monto_total)),
    ntercil = ntile(monto_total, 3)
    ) %>%
  arrange(region, ranking) %>%
  ungroup()

Ranking
# A tibble: 5 × 5
  region vendedor    monto_total ranking ntercil
  <chr>  <chr>             <dbl>   <dbl>   <int>
1 norte  Luis            9500000       1       2
2 norte  Ana               31000       2       1
3 sur    Desconocido       23500       1       3
4 sur    Pedro             22000       2       2
5 sur    Carmen            21000       3       1

5 Resumen analítico

Code
resumen_ventas <- ventas_crudas %>%
  filter(completada == "SI") %>%
  group_by(vendedor) %>%
  summarise(
    total_completadas = n(),
    monto_total       = sum(monto, na.rm = TRUE),
    monto_promedio    = mean(monto, na.rm = TRUE),
    comision_total    = sum(comision, na.rm = TRUE)
  ) %>%
  arrange(desc(monto_total))

resumen_ventas
# A tibble: 5 × 5
  vendedor    total_completadas monto_total monto_promedio comision_total
  <chr>                   <int>       <dbl>          <dbl>          <dbl>
1 Luis                        1     9500000        9500000         475000
2 Ana                         2       31000          15500           1550
3 Desconocido                 1       23500          23500           1175
4 Pedro                       1       22000          22000           1100
5 Carmen                      1       21000          21000           1050