Este informe analiza de forma descriptiva y exploratoria el desempeño comercial y financiero de distintas líneas de productos de ADIDAS. El análisis parte de las variables disponibles en la base: distribuidor, región, estado, ciudad, producto, precio por unidad, unidades vendidas, ventas totales, utilidad operativa, margen operativo y método de venta.
Además de las preguntas orientadoras del caso, se incorporan preguntas de negocio adicionales: ¿qué segmentos convierten mejor las ventas en utilidad?, ¿existe concentración del negocio?, ¿qué combinaciones producto–canal reúnen escala y margen?, ¿qué mercados presentan alto volumen pero menor rentabilidad?, y ¿qué tan consistente es la relación entre precio, volumen y margen?
Nota metodológica: la base no contiene una variable temporal. Por esta razón no se calcula crecimiento interperiodo, ya que hacerlo requeriría inventar una dimensión que no está disponible.
datos <- read_excel("C:/Users/Usuario/Desktop/ANALÍT. DE DATOS PARA LA TOMA DE DECISONES/DatosCaso1.xlsx")
n_filas <- nrow(datos)
n_columnas <- ncol(datos)
resumen_calidad <- tibble(
indicador = c(
"Filas", "Columnas", "Celdas faltantes",
"Filas duplicadas exactas", "Registros con ventas = 0"
),
valor = c(
n_filas,
n_columnas,
sum(is.na(datos)),
sum(duplicated(datos)),
sum(datos$ventas_total == 0, na.rm = TRUE)
)
)
kable(resumen_calidad, caption = "Diagnóstico básico de la base")
| indicador | valor |
|---|---|
| Filas | 9648 |
| Columnas | 11 |
| Celdas faltantes | 0 |
| Filas duplicadas exactas | 262 |
| Registros con ventas = 0 | 4 |
La base contiene 9648 registros y 11 variables. No se observan valores faltantes en las variables analizadas. Se detectan filas duplicadas exactas, por lo que estas no deben eliminarse automáticamente sin conocer si representan registros repetidos o transacciones separadas con exactamente los mismos valores.
consistencia <- tibble(
prueba = c(
"Ventas = precio × unidades",
"Utilidad = ventas × margen"
),
registros_inconsistentes = c(
sum(abs(datos$precio_unidad * datos$unidades_vendidas - datos$ventas_total) > 1e-8),
sum(abs(datos$ventas_total * datos$margen_operativo - datos$utilidad_operativa) > 1e-8)
)
)
kable(consistencia, caption = "Pruebas de consistencia aritmética")
| prueba | registros_inconsistentes |
|---|---|
| Ventas = precio × unidades | 0 |
| Utilidad = ventas × margen | 0 |
Las relaciones aritméticas entre precio, unidades, ventas, utilidad y margen son consistentes. Esto es relevante porque permite interpretar la utilidad como el resultado conjunto de volumen × precio × margen.
total_ventas <- sum(datos$ventas_total, na.rm = TRUE)
total_unidades <- sum(datos$unidades_vendidas, na.rm = TRUE)
total_utilidad <- sum(datos$utilidad_operativa, na.rm = TRUE)
margen_ponderado <- total_utilidad / total_ventas
margen_promedio <- mean(datos$margen_operativo, na.rm = TRUE)
ventas_promedio_registro <- mean(datos$ventas_total, na.rm = TRUE)
unidades_promedio_registro <- mean(datos$unidades_vendidas, na.rm = TRUE)
precio_promedio_ponderado <- total_ventas / total_unidades
kpis <- tibble(
Indicador = c(
"Ventas totales",
"Unidades vendidas",
"Utilidad operativa",
"Margen operativo ponderado",
"Margen operativo promedio simple",
"Precio promedio por unidad (ponderado por unidades)",
"Ventas promedio por registro"
),
Valor = c(
dollar(total_ventas, prefix = "USD ", big.mark = ".", decimal.mark = ",", accuracy = 1),
number(total_unidades, big.mark = ".", decimal.mark = ",", accuracy = 1),
dollar(total_utilidad, prefix = "USD ", big.mark = ".", decimal.mark = ",", accuracy = 1),
percent(margen_ponderado, accuracy = 0.1, decimal.mark = ","),
percent(margen_promedio, accuracy = 0.1, decimal.mark = ","),
dollar(precio_promedio_ponderado, prefix = "USD ", accuracy = 0.01),
dollar(ventas_promedio_registro, prefix = "USD ", accuracy = 1)
)
)
kable(kpis, caption = "Indicadores consolidados")
| Indicador | Valor |
|---|---|
| Ventas totales | USD 120.166.650 |
| Unidades vendidas | 2.478.861 |
| Utilidad operativa | USD 47.224.968 |
| Margen operativo ponderado | 39,3% |
| Margen operativo promedio simple | 42,3% |
| Precio promedio por unidad (ponderado por unidades) | USD 48.48 |
| Ventas promedio por registro | USD 12,455 |
El margen promedio simple es superior al margen ponderado por ventas. Esto indica que los registros de mayor peso comercial presentan, en conjunto, márgenes menores que el promedio simple de observaciones. Por ello, para una lectura financiera agregada se prioriza el margen ponderado por ventas.
producto <- datos %>%
group_by(producto) %>%
summarise(
registros = n(),
unidades = sum(unidades_vendidas),
ventas = sum(ventas_total),
utilidad = sum(utilidad_operativa),
margen = utilidad / ventas,
.groups = "drop"
) %>%
mutate(
participacion_ventas = ventas / total_ventas,
participacion_utilidad = utilidad / total_utilidad,
brecha_pp = (participacion_utilidad - participacion_ventas) * 100
) %>%
arrange(desc(ventas))
kable(
producto %>%
mutate(
ventas = dollar(ventas, prefix = "USD ", accuracy = 1),
utilidad = dollar(utilidad, prefix = "USD ", accuracy = 1),
margen = percent(margen, accuracy = 0.1),
participacion_ventas = percent(participacion_ventas, accuracy = 0.1),
participacion_utilidad = percent(participacion_utilidad, accuracy = 0.1),
brecha_pp = paste0(number(brecha_pp, accuracy = 0.1, decimal.mark = ","), " pp")
) %>%
select(producto, registros, unidades, ventas, utilidad, margen,
participacion_ventas, participacion_utilidad, brecha_pp),
caption = "Desempeño por producto"
)
| producto | registros | unidades | ventas | utilidad | margen | participacion_ventas | participacion_utilidad | brecha_pp |
|---|---|---|---|---|---|---|---|---|
| Men’s Street Footwear | 1610 | 593320 | USD 27,680,769 | USD 11,629,046 | 42.0% | 23.0% | 24.6% | 1,6 pp |
| Women’s Apparel | 1608 | 433827 | USD 23,870,985 | USD 9,685,221 | 40.6% | 19.9% | 20.5% | 0,6 pp |
| Men’s Athletic Footwear | 1610 | 435526 | USD 20,577,180 | USD 7,437,457 | 36.1% | 17.1% | 15.7% | -1,4 pp |
| Women’s Street Footwear | 1608 | 392269 | USD 17,201,563 | USD 6,494,017 | 37.8% | 14.3% | 13.8% | -0,6 pp |
| Men’s Apparel | 1606 | 306683 | USD 16,520,632 | USD 6,381,405 | 38.6% | 13.7% | 13.5% | -0,2 pp |
| Women’s Athletic Footwear | 1606 | 317236 | USD 14,315,521 | USD 5,597,822 | 39.1% | 11.9% | 11.9% | -0,1 pp |
producto_largo <- producto %>%
select(producto, participacion_ventas, participacion_utilidad) %>%
pivot_longer(-producto, names_to = "indicador", values_to = "participacion") %>%
mutate(
indicador = recode(indicador,
participacion_ventas = "Participación en ventas",
participacion_utilidad = "Participación en utilidad")
)
ggplot(producto_largo,
aes(x = reorder(producto, participacion), y = participacion, fill = indicador)) +
geom_col(position = position_dodge(width = 0.75), width = 0.68) +
geom_text(aes(label = percent(participacion, accuracy = 0.1)),
position = position_dodge(width = 0.75), hjust = -0.08, size = 3.4) +
coord_flip() +
scale_y_continuous(labels = percent_format(accuracy = 1), expand = expansion(mult = c(0, 0.12))) +
labs(
title = "Aporte de cada categoría a ventas y utilidad operativa",
subtitle = "La brecha entre ambas participaciones identifica categorías cuya contribución a utilidad es mayor o menor que su peso comercial",
x = NULL, y = "Participación (%)", fill = NULL,
caption = "Fuente: elaboración propia con base en DatosCaso1.xlsx"
) +
theme_minimal(base_size = 12) +
theme(legend.position = "bottom")
Hallazgo: Men’s Street Footwear concentra 23,0% de las ventas y 24,6% de la utilidad, mientras que Men’s Athletic Footwear aporta 17,1% de las ventas pero 15,7% de la utilidad. La comparación no debe quedarse en volumen: permite identificar dónde el negocio está convirtiendo mejor sus ventas en resultado.
canal <- datos %>%
group_by(metodo_venta) %>%
summarise(
registros = n(),
unidades = sum(unidades_vendidas),
ventas = sum(ventas_total),
utilidad = sum(utilidad_operativa),
margen = utilidad / ventas,
.groups = "drop"
) %>%
mutate(
participacion_ventas = ventas / total_ventas,
participacion_utilidad = utilidad / total_utilidad,
brecha_pp = (participacion_utilidad - participacion_ventas) * 100
) %>%
arrange(desc(ventas))
kable(
canal %>%
mutate(
ventas = dollar(ventas, prefix = "USD ", accuracy = 1),
utilidad = dollar(utilidad, prefix = "USD ", accuracy = 1),
margen = percent(margen, accuracy = 0.1),
participacion_ventas = percent(participacion_ventas, accuracy = 0.1),
participacion_utilidad = percent(participacion_utilidad, accuracy = 0.1),
brecha_pp = paste0(number(brecha_pp, accuracy = 0.1, decimal.mark = ","), " pp")
) %>%
select(metodo_venta, registros, unidades, ventas, utilidad, margen,
participacion_ventas, participacion_utilidad, brecha_pp),
caption = "Desempeño por método de venta"
)
| metodo_venta | registros | unidades | ventas | utilidad | margen | participacion_ventas | participacion_utilidad | brecha_pp |
|---|---|---|---|---|---|---|---|---|
| Online | 4889 | 939093 | USD 44,965,657 | USD 19,552,538 | 43.5% | 37.4% | 41.4% | 4,0 pp |
| Outlet | 3019 | 849778 | USD 39,536,618 | USD 14,913,301 | 37.7% | 32.9% | 31.6% | -1,3 pp |
| In-store | 1740 | 689990 | USD 35,664,375 | USD 12,759,129 | 35.8% | 29.7% | 27.0% | -2,7 pp |
canal_largo <- canal %>%
select(metodo_venta, participacion_ventas, participacion_utilidad) %>%
pivot_longer(-metodo_venta, names_to = "indicador", values_to = "participacion") %>%
mutate(indicador = recode(indicador,
participacion_ventas = "Participación en ventas",
participacion_utilidad = "Participación en utilidad"))
ggplot(canal_largo, aes(x = metodo_venta, y = participacion, fill = indicador)) +
geom_col(position = position_dodge(width = 0.75), width = 0.65) +
geom_text(aes(label = percent(participacion, accuracy = 0.1)),
position = position_dodge(width = 0.75), vjust = -0.35, size = 3.6) +
scale_y_continuous(labels = percent_format(accuracy = 1), expand = expansion(mult = c(0, 0.14))) +
labs(
title = "El canal Online convierte una mayor proporción de ventas en utilidad",
subtitle = "Brecha utilidad − ventas: Online +4,0 pp; In-store −2,7 pp; Outlet −1,3 pp",
x = NULL, y = "Participación (%)", fill = NULL,
caption = "Fuente: elaboración propia con base en DatosCaso1.xlsx"
) +
theme_minimal(base_size = 12) +
theme(legend.position = "bottom")
Hallazgo: Online concentra 37,4% de las ventas pero 41,4% de la utilidad y presenta un margen ponderado de 43,5%. La diferencia entre participación comercial y participación en utilidad es una señal descriptiva de mejor conversión económica en este canal.
region <- datos %>%
group_by(region) %>%
summarise(
registros = n(),
unidades = sum(unidades_vendidas),
ventas = sum(ventas_total),
utilidad = sum(utilidad_operativa),
margen = utilidad / ventas,
.groups = "drop"
) %>%
mutate(
participacion_ventas = ventas / total_ventas,
participacion_utilidad = utilidad / total_utilidad,
brecha_pp = (participacion_utilidad - participacion_ventas) * 100
) %>%
arrange(desc(ventas))
kable(
region %>%
mutate(
ventas = dollar(ventas, prefix = "USD ", accuracy = 1),
utilidad = dollar(utilidad, prefix = "USD ", accuracy = 1),
margen = percent(margen, accuracy = 0.1),
participacion_ventas = percent(participacion_ventas, accuracy = 0.1),
participacion_utilidad = percent(participacion_utilidad, accuracy = 0.1),
brecha_pp = paste0(number(brecha_pp, accuracy = 0.1, decimal.mark = ","), " pp")
) %>%
select(region, registros, unidades, ventas, utilidad, margen,
participacion_ventas, participacion_utilidad, brecha_pp),
caption = "Desempeño por región"
)
| region | registros | unidades | ventas | utilidad | margen | participacion_ventas | participacion_utilidad | brecha_pp |
|---|---|---|---|---|---|---|---|---|
| West | 2448 | 686985 | USD 36,436,157 | USD 13,017,584 | 35.7% | 30.3% | 27.6% | -2,8 pp |
| Northeast | 2376 | 501279 | USD 25,078,267 | USD 9,732,774 | 38.8% | 20.9% | 20.6% | -0,3 pp |
| Southeast | 1224 | 407000 | USD 21,374,436 | USD 8,393,059 | 39.3% | 17.8% | 17.8% | 0,0 pp |
| South | 1728 | 492260 | USD 20,603,356 | USD 9,221,605 | 44.8% | 17.1% | 19.5% | 2,4 pp |
| Midwest | 1872 | 391337 | USD 16,674,434 | USD 6,859,945 | 41.1% | 13.9% | 14.5% | 0,7 pp |
region_plot <- region %>% arrange(participacion_ventas)
ggplot(region_plot, aes(x = reorder(region, participacion_ventas), y = participacion_ventas)) +
geom_col() +
geom_text(aes(label = paste0(
percent(participacion_ventas, accuracy = 0.1),
" | utilidad ", percent(participacion_utilidad, accuracy = 0.1),
" | margen ", percent(margen, accuracy = 0.1)
)), hjust = -0.03, size = 3.2) +
coord_flip() +
scale_y_continuous(labels = percent_format(accuracy = 1), expand = expansion(mult = c(0, 0.27))) +
labs(
title = "Concentración regional: volumen y rentabilidad no coinciden",
subtitle = "La participación de la utilidad y el margen ponderado permiten detectar diferencias de conversión económica",
x = NULL, y = "Participación en ventas (%)",
caption = "Fuente: elaboración propia con base en DatosCaso1.xlsx"
) +
theme_minimal(base_size = 12)
Hallazgo: West genera 30,3% de las ventas, pero solo 27,6% de la utilidad, con un margen de 35,7%. South, en contraste, representa 17,1% de las ventas y 19,5% de la utilidad, con un margen de 44,8%. Esto muestra por qué la lectura exclusiva de ventas puede ocultar diferencias importantes de rentabilidad.
producto_canal <- datos %>%
group_by(producto, metodo_venta) %>%
summarise(
unidades = sum(unidades_vendidas),
ventas = sum(ventas_total),
utilidad = sum(utilidad_operativa),
margen = utilidad / ventas,
.groups = "drop"
)
ggplot(producto_canal,
aes(x = ventas / 1e6, y = margen, size = utilidad / 1e6)) +
geom_point(alpha = 0.65) +
geom_text(aes(label = paste(producto, metodo_venta, sep = "\n")),
nudge_y = 0.004, size = 2.9, check_overlap = TRUE) +
geom_hline(yintercept = margen_ponderado, linetype = "dashed") +
geom_vline(xintercept = mean(producto_canal$ventas) / 1e6, linetype = "dashed") +
scale_y_continuous(labels = percent_format(accuracy = 1)) +
labs(
title = "Mapa producto–canal: escala, margen y utilidad",
subtitle = "El tamaño de la burbuja representa la utilidad operativa; las líneas marcan los promedios de referencia",
x = "Ventas del segmento (USD millones)",
y = "Margen operativo ponderado (%)",
size = "Utilidad (USD M)",
caption = "Fuente: elaboración propia con base en DatosCaso1.xlsx"
) +
theme_minimal(base_size = 12) +
theme(legend.position = "right")
Este gráfico es especialmente útil para una presentación ejecutiva porque integra tres dimensiones en una sola vista. Men’s Street Footwear–Online y Women’s Apparel–Online se ubican entre las combinaciones con mayor escala y margen, mientras que varias combinaciones In-store y algunas de Athletic Footwear muestran menores márgenes.
ciudad <- datos %>%
group_by(ciudad) %>%
summarise(
unidades = sum(unidades_vendidas),
ventas = sum(ventas_total),
utilidad = sum(utilidad_operativa),
margen = utilidad / ventas,
.groups = "drop"
)
ciudades_etiqueta <- ciudad %>%
slice_max(order_by = ventas, n = 10) %>%
bind_rows(ciudad %>% slice_min(order_by = margen, n = 3)) %>%
distinct(ciudad, .keep_all = TRUE)
ggplot(ciudad, aes(x = ventas / 1e6, y = margen, size = unidades)) +
geom_point(alpha = 0.55) +
geom_text(data = ciudades_etiqueta,
aes(label = ciudad), nudge_x = 0.03, nudge_y = 0.003,
size = 3, check_overlap = TRUE) +
geom_hline(yintercept = margen_ponderado, linetype = "dashed") +
geom_vline(xintercept = median(ciudad$ventas) / 1e6, linetype = "dashed") +
scale_y_continuous(labels = percent_format(accuracy = 1)) +
labs(
title = "Ciudades: identificar mercados que combinan escala y margen",
subtitle = "El tamaño de la burbuja representa unidades vendidas; se etiquetan los principales mercados y algunos márgenes bajos",
x = "Ventas de la ciudad (USD millones)",
y = "Margen operativo ponderado (%)",
size = "Unidades vendidas",
caption = "Fuente: elaboración propia con base en DatosCaso1.xlsx"
) +
theme_minimal(base_size = 12)
Hallazgo: San Francisco, Seattle, New York y otras ciudades importantes presentan ventas relevantes pero márgenes por debajo del margen global. En cambio, ciudades como Charleston, Houston, New Orleans y Dallas combinan un volumen relevante con márgenes superiores al agregado. Se recomienda analizar estas diferencias antes de tomar decisiones de asignación de inventario o promociones.
region_producto <- datos %>%
group_by(region, producto) %>%
summarise(
ventas = sum(ventas_total),
utilidad = sum(utilidad_operativa),
margen = utilidad / ventas,
.groups = "drop"
)
ggplot(region_producto,
aes(x = producto, y = region, fill = margen)) +
geom_tile() +
geom_text(aes(label = paste0(percent(margen, accuracy = 0.1), "\nUSD ",
number(ventas / 1e6, accuracy = 0.01, decimal.mark = ","), " M")),
size = 3.0) +
scale_fill_continuous(labels = percent_format(accuracy = 1)) +
labs(
title = "Rentabilidad por combinación región–producto",
subtitle = "El color representa el margen operativo y la etiqueta muestra margen y ventas",
x = "Producto", y = "Región", fill = "Margen",
caption = "Fuente: elaboración propia con base en DatosCaso1.xlsx"
) +
theme_minimal(base_size = 11) +
theme(axis.text.x = element_text(angle = 25, hjust = 1),
panel.grid = element_blank())
La matriz permite encontrar oportunidades que desaparecen cuando solo se observa el total regional o el total por producto. Un caso particularmente visible es Women’s Apparel en South, con margen de 52,1% y ventas superiores a USD 4,2 millones. En el extremo opuesto, Women’s Apparel en West combina ventas cercanas a USD 7,0 millones con un margen de 29,8%, por lo que el tamaño del mercado no garantiza una conversión equivalente en utilidad.
ggplot(datos, aes(x = margen_operativo, y = reorder(producto, margen_operativo, FUN = median))) +
geom_boxplot() +
geom_vline(xintercept = margen_ponderado, linetype = "dashed") +
scale_x_continuous(labels = percent_format(accuracy = 1)) +
labs(
title = "Variabilidad del margen operativo por producto",
subtitle = "La distribución permite distinguir productos con margen típico alto de aquellos con mayor dispersión; la línea marca el margen global ponderado",
x = "Margen operativo (%)", y = NULL,
caption = "Fuente: elaboración propia con base en DatosCaso1.xlsx"
) +
theme_minimal(base_size = 12)
El boxplot permite complementar el promedio con una lectura de dispersión. Women’s Apparel y Men’s Street Footwear presentan medianas relativamente altas, pero también una dispersión importante. Esto refuerza la necesidad de revisar las combinaciones concretas de región, canal y distribuidor antes de atribuir un nivel de margen a toda la categoría.
r_precio_unidades <- cor(datos$precio_unidad, datos$unidades_vendidas, use = "complete.obs")
r_precio_margen <- cor(datos$precio_unidad, datos$margen_operativo, use = "complete.obs")
r_ventas_margen <- cor(datos$ventas_total, datos$margen_operativo, use = "complete.obs")
correlaciones <- tibble(
Relacion = c("Precio vs. unidades", "Precio vs. margen", "Ventas vs. margen"),
Pearson_r = c(r_precio_unidades, r_precio_margen, r_ventas_margen)
)
kable(correlaciones, digits = 3, caption = "Correlaciones seleccionadas")
| Relacion | Pearson_r |
|---|---|
| Precio vs. unidades | 0.266 |
| Precio vs. margen | -0.137 |
| Ventas vs. margen | -0.302 |
ggplot(datos, aes(x = precio_unidad, y = unidades_vendidas)) +
geom_point(alpha = 0.18) +
geom_smooth(method = "lm", se = FALSE) +
labs(
title = "Precio y volumen: no se observa una relación inversa en esta base",
subtitle = paste0("Correlación de Pearson r = ", number(r_precio_unidades, accuracy = 0.001, decimal.mark = ","),
"; el resultado es descriptivo y no implica causalidad"),
x = "Precio por unidad (USD)",
y = "Unidades vendidas por registro",
caption = "Fuente: elaboración propia con base en DatosCaso1.xlsx"
) +
theme_minimal(base_size = 12)
La correlación precio–unidades es positiva y moderada
(r_precio_unidades), por lo que en esta base no aparece el
patrón simple de “mayor precio = menor volumen”. Este resultado no
prueba que aumentar el precio genere más unidades; el comportamiento
también puede reflejar la combinación de producto, región, canal y
distribuidor.
ggplot(datos, aes(x = ventas_total / 1000, y = margen_operativo)) +
geom_point(alpha = 0.18) +
geom_smooth(method = "lm", se = FALSE) +
scale_y_continuous(labels = percent_format(accuracy = 1)) +
labs(
title = "Mayor venta por registro no implica mayor margen",
subtitle = paste0("Correlación de Pearson r = ", number(r_ventas_margen, accuracy = 0.001, decimal.mark = ","),
"; el margen promedio simple es ", percent(margen_promedio, accuracy = 0.1),
" frente a ", percent(margen_ponderado, accuracy = 0.1), " ponderado por ventas"),
x = "Ventas por registro (USD miles)",
y = "Margen operativo (%)",
caption = "Fuente: elaboración propia con base en DatosCaso1.xlsx"
) +
theme_minimal(base_size = 12)
La relación ventas–margen es negativa moderada. Esto refuerza un punto de negocio: algunas de las observaciones con mayor volumen también pueden operar con márgenes menores. Por eso, maximizar ventas sin considerar el margen puede generar una lectura incompleta del desempeño.
distribuidor <- datos %>%
group_by(distribuidor) %>%
summarise(
registros = n(),
unidades = sum(unidades_vendidas),
ventas = sum(ventas_total),
utilidad = sum(utilidad_operativa),
margen = utilidad / ventas,
ventas_por_registro = ventas / registros,
.groups = "drop"
) %>%
arrange(desc(ventas))
kable(
distribuidor %>%
mutate(
ventas = dollar(ventas, prefix = "USD ", accuracy = 1),
utilidad = dollar(utilidad, prefix = "USD ", accuracy = 1),
margen = percent(margen, accuracy = 0.1),
ventas_por_registro = dollar(ventas_por_registro, prefix = "USD ", accuracy = 1)
),
caption = "Desempeño por distribuidor"
)
| distribuidor | registros | unidades | ventas | utilidad | margen | ventas_por_registro |
|---|---|---|---|---|---|---|
| West Gear | 2374 | 625262 | USD 32,409,558 | USD 12,196,891 | 37.6% | USD 13,652 |
| Foot Locker | 2637 | 604369 | USD 29,024,945 | USD 11,317,027 | 39.0% | USD 11,007 |
| Sports Direct | 2032 | 557640 | USD 24,616,622 | USD 10,641,609 | 43.2% | USD 12,114 |
| Kohl’s | 1030 | 287375 | USD 13,512,453 | USD 5,182,260 | 38.4% | USD 13,119 |
| Walmart | 626 | 206225 | USD 10,506,085 | USD 3,902,749 | 37.1% | USD 16,783 |
| Amazon | 949 | 197990 | USD 10,096,987 | USD 3,984,432 | 39.5% | USD 10,640 |
ggplot(distribuidor, aes(x = ventas / 1e6, y = margen, size = unidades)) +
geom_point(alpha = 0.7) +
geom_text(aes(label = distribuidor), nudge_x = 0.15, nudge_y = 0.004, size = 3.2) +
geom_hline(yintercept = margen_ponderado, linetype = "dashed") +
scale_y_continuous(labels = percent_format(accuracy = 1)) +
labs(
title = "Distribuidores: la escala de ventas no equivale a la misma rentabilidad",
subtitle = "El tamaño representa unidades vendidas y la línea muestra el margen operativo global",
x = "Ventas del distribuidor (USD millones)",
y = "Margen operativo ponderado (%)",
size = "Unidades vendidas",
caption = "Fuente: elaboración propia con base en DatosCaso1.xlsx"
) +
theme_minimal(base_size = 12)
La cobertura de registros difiere entre distribuidores, por lo que las ventas totales deben leerse junto con el número de observaciones y el margen. Por ejemplo, Sports Direct tiene una participación menor en ventas que West Gear, pero una mayor participación en utilidad y un margen superior.
q_ventas <- quantile(datos$ventas_total, c(0.25, 0.75), na.rm = TRUE)
iqr_ventas <- q_ventas[2] - q_ventas[1]
lim_sup_ventas <- q_ventas[2] + 1.5 * iqr_ventas
q_utilidad <- quantile(datos$utilidad_operativa, c(0.25, 0.75), na.rm = TRUE)
iqr_utilidad <- q_utilidad[2] - q_utilidad[1]
lim_sup_utilidad <- q_utilidad[2] + 1.5 * iqr_utilidad
outliers <- tibble(
Variable = c("Ventas totales", "Utilidad operativa", "Unidades vendidas", "Margen operativo"),
Limite_superior_IQR = c(
lim_sup_ventas,
lim_sup_utilidad,
quantile(datos$unidades_vendidas, 0.75, na.rm = TRUE) +
1.5 * (quantile(datos$unidades_vendidas, 0.75, na.rm = TRUE) - quantile(datos$unidades_vendidas, 0.25, na.rm = TRUE)),
quantile(datos$margen_operativo, 0.75, na.rm = TRUE) +
1.5 * (quantile(datos$margen_operativo, 0.75, na.rm = TRUE) - quantile(datos$margen_operativo, 0.25, na.rm = TRUE))
),
Registros_atipicos = c(
sum(datos$ventas_total > lim_sup_ventas, na.rm = TRUE),
sum(datos$utilidad_operativa > lim_sup_utilidad, na.rm = TRUE),
sum(datos$unidades_vendidas > (quantile(datos$unidades_vendidas, 0.75, na.rm = TRUE) + 1.5 * (quantile(datos$unidades_vendidas, 0.75, na.rm = TRUE) - quantile(datos$unidades_vendidas, 0.25, na.rm = TRUE))), na.rm = TRUE),
sum(datos$margen_operativo > (quantile(datos$margen_operativo, 0.75, na.rm = TRUE) + 1.5 * (quantile(datos$margen_operativo, 0.75, na.rm = TRUE) - quantile(datos$margen_operativo, 0.25, na.rm = TRUE))), na.rm = TRUE)
)
)
kable(outliers, digits = 2, caption = "Diagnóstico de valores atípicos por criterio IQR")
| Variable | Limite_superior_IQR | Registros_atipicos |
|---|---|---|
| Ventas totales | 33563.38 | 799 |
| Utilidad operativa | 12850.74 | 694 |
| Unidades vendidas | 716.00 | 508 |
| Margen operativo | 0.70 | 58 |
Los valores atípicos deben tratarse como una señal de análisis, no como errores automáticos. En una base comercial, una venta excepcional puede ser un evento perfectamente válido. El análisis debe distinguir entre una observación atípica, una operación especial y un problema de calidad de datos.
El desempeño debe evaluarse simultáneamente con ventas y rentabilidad. El margen operativo global ponderado es 39,3%, mientras que el promedio simple de márgenes es 42,3%. La diferencia muestra que los registros de mayor peso económico tienen márgenes relativamente menores.
Men’s Street Footwear es una categoría central del negocio. Aporta 23,0% de las ventas y 24,6% de la utilidad, con un margen ponderado cercano al 42,0%.
Online destaca por conversión económica. Representa 37,4% de las ventas y 41,4% de la utilidad, con un margen de 43,5%, superior al de In-store y Outlet.
West concentra escala, pero con menor conversión de ventas en utilidad. Aporta 30,3% de las ventas y 27,6% de la utilidad, con 35,7% de margen.
South muestra una conversión más favorable. Aporta 17,1% de las ventas y 19,5% de la utilidad, con 44,8% de margen.
La rentabilidad cambia por combinación, no solo por producto o región. Women’s Apparel en South alcanza 52,1% de margen, mientras Women’s Apparel en West registra 29,8%, aun cuando West tiene mayor nivel de ventas para esa categoría.
El precio por sí solo no explica el volumen. La
correlación precio–unidades es positiva moderada
(r_precio_unidades). El resultado debe interpretarse como
asociación, no como causalidad.
Las ventas altas no garantizan márgenes altos.
La relación ventas–margen es negativa moderada
(r_ventas_margen), por lo que la expansión de volumen
debería acompañarse de seguimiento de rentabilidad.
La calidad de los datos requiere una validación previa al uso operativo. Se observan duplicados exactos y cuatro registros con cero unidades y cero ventas. No se recomienda borrar automáticamente esas filas; primero debe definirse qué representa cada registro.
La mezcla de ventas debe complementarse con participación en utilidad y margen ponderado. Men’s Street Footwear y Women’s Apparel tienen una contribución importante y, en ciertas combinaciones, una conversión favorable.
El canal Online presenta una participación de utilidad superior a su participación de ventas. Como recomendación prescriptiva, conviene investigar qué factores operativos y comerciales explican esta diferencia y evaluar si pueden replicarse parcialmente en otros canales sin deteriorar el margen.
West representa el principal bloque de ventas, pero su margen es inferior al agregado. La recomendación no es reducir automáticamente el negocio, sino descomponer el resultado por producto, distribuidor y ciudad para detectar dónde se origina la brecha de margen.
Combinaciones como Women’s Apparel–South muestran que existen bolsillos de rentabilidad elevada. La siguiente etapa analítica debería comprobar si el patrón es consistente y qué características de producto, precio, canal o distribuidor están asociadas con él.
Para futuras decisiones de inventario, promociones o asignación comercial, una opción más robusta es utilizar una matriz de escala (ventas/unidades) × rentabilidad (margen/utilidad), evitando decisiones basadas exclusivamente en ventas.
Para la presentación ejecutiva no es necesario mostrar todos los gráficos. Los cinco que mejor condensan la historia de negocio son:
La presentación debe acompañar cada gráfico con una frase de interpretación, no solo con la descripción de la figura.
Fuente general: elaboración propia a partir del
archivo DatosCaso1.xlsx, suministrado para el Caso 1 de
Analítica Descriptiva.