Code
#| echo: true
library (tidyverse)
library(dplyr)#| echo: true
library (tidyverse)
library(dplyr)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
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", "…
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
colSums(is.na(ventas_crudas)) id_venta vendedor region monto mes completada
0 1 0 1 0 1
Comentarios:
# 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.Para respaldar el diagnóstico, lo mostraré con codigo:
colSums(is.na(ventas_crudas)) id_venta vendedor region monto mes completada
0 1 0 1 0 1
sum(duplicated(ventas_crudas))[1] 1
# 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
# 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
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
#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
# 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", "…
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>
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.
#| 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
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