semana06_AshleyMedina

Autor/a

Ashley Medina

Fecha de publicación

14 de junio de 2026

Código
# Cargar las librerías necesarias
library(dplyr)
library(tidyr)
library(stringr)

1 Dataset de práctica:

Código
# Definición del dataset original
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")
)

# Mostrar tabla cruda
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 Parte 1 — Diagnóstico inicial:

Código
# Estructura de los datos y tipos de columnas
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", "…
Código
# Resumen estadístico general
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  
               
Código
# Conteo exacto de valores nulos (NAs) por columna
colSums(is.na(ventas_crudas))
  id_venta   vendedor     region      monto        mes completada 
         0          1          0          1          0          1 
Código
# Conteo de filas completamente duplicadas o duplicadas por id_venta
sum(duplicated(ventas_crudas$id_venta))
[1] 1

2.1 Diagnóstico inicial:

  • Duplicados: hay 1 fila duplicada (El id_venta = 3 de “María” aparece dos veces idéntico al final).

  • Valores NAs por columna:

    • vendedor: 1 NA

    • monto: 1 NA

    • completada: 1 NA

  • Sí hay un outlier crítico en la columna monto. La venta del ID 8 asignada a “luis” tiene un monto de 9,500,000, un valor desproporcionado comparado con el resto que ronda los 15,000 - 31,000.

3 Parte 2 — Limpieza:

Código
# Proceso de Limpieza en cadena de bloques utilizando dplyr y tidyr
ventas_limpias <- ventas_crudas %>%
  # 1. Eliminar filas duplicadas basadas en id_venta
  distinct(id_venta, .keep_all = TRUE) %>%
  
  # 2. Limpiar vendedor y region (quitar espacios en blanco y dejar formato Title/Lower case)
  mutate(
    vendedor = str_to_title(str_trim(vendedor)),
    region   = str_to_lower(str_trim(region))
  ) %>%
  
  # 3. Imputar el NA de vendedor con "Desconocido"
  mutate(vendedor = replace_na(vendedor, "Desconocido")) %>%
  
  # 4. Imputar el NA de monto con la mediana del mes correspondiente
  group_by(mes) %>%
  mutate(monto = replace_na(monto, median(monto, na.rm = TRUE))) %>%
  ungroup() %>% # Desagrupar para evitar afectar las operaciones siguientes
  
  # 5. Convertir 'completada' a factor aplicando "NO" a los NAs
  mutate(
    completada = replace_na(completada, "NO"),
    completada = as.factor(completada)
  ) %>%
  
 # 6. Marcar el outlier en monto con una columna booleana usando el criterio IQR
  mutate(
    q1         = quantile(monto, 0.25),
    q3         = quantile(monto, 0.75),
    iqr_val    = q3 - q1,
    es_outlier = monto > (q3 + 1.5 * iqr_val) | monto < (q1 - 1.5 * iqr_val)
  ) %>%
  # Remover variables estadísticas auxiliares
  select(-q1, -q3, -iqr_val)

# Mostrar el resultado del dataset limpio
ventas_limpias
# 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 Parte 3 — Transformación con dplyr:

Código
ventas_transformadas <- ventas_limpias %>%
  # 1. Calcular comisión: 5% si completada == "SI", 0 si no
  mutate(comision = if_else(completada == "SI", monto * 0.05, 0)) %>%
  
  # 2. Clasificar la categoría de la venta con case_when()
  mutate(categoria_venta = case_when(
    monto < 15000  ~ "Baja",
    monto >= 15000 & monto <= 25000 ~ "Media",
    monto > 25000  ~ "Alta"
  )) %>%
  
  # 3. Calcular el ranking del vendedor por monto dentro de cada región
  group_by(region) %>%
  mutate(ranking_vendedor = rank(desc(monto), ties.method = "first")) %>%
  ungroup()

# Mostrar el resultado de las transformaciones
ventas_transformadas
# A tibble: 10 × 10
   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
# ℹ 2 more variables: categoria_venta <chr>, ranking_vendedor <int>

5 Parte 4 — Resumen analítico:

Código
resumen_vendedores <- ventas_transformadas %>%
  group_by(vendedor) %>%
  summarise(
    total_ventas_completadas = sum(completada == "SI"),
    monto_total_vendido      = sum(monto),
    monto_promedio_por_venta = mean(monto),
    comision_total_ganada    = sum(comision),
    .groups = "drop"
  ) %>%
  # Ordenar de mayor a menor monto total vendido
  arrange(desc(monto_total_vendido))

# Visualizar la tabla de desempeño final
resumen_vendedores
# A tibble: 6 × 5
  vendedor    total_ventas_completa…¹ monto_total_vendido monto_promedio_por_v…²
  <chr>                         <int>               <dbl>                  <dbl>
1 Luis                              1             9517500                4758750
2 Carmen                            1               52000                  26000
3 Pedro                             1               41500                  20750
4 Ana                               2               31000                  15500
5 Desconocido                       1               23500                  23500
6 María                             0               18500                  18500
# ℹ abbreviated names: ¹​total_ventas_completadas, ²​monto_promedio_por_venta
# ℹ 1 more variable: comision_total_ganada <dbl>