En el presente informe se realiza un análisis descriptivo y exploratorio de un conjunto de datos de ventas de Adidas. El objetivo es comprender el comportamiento de las ventas, la rentabilidad y las relaciones entre las variables clave para identificar patrones, fortalezas y oportunidades de mejora en la estrategia comercial, para finalmente poder establecer qué combinaciones estratégicas resultan mejor para la compañía.
Este enfoque parte del interés de observar cómo los datos nos pueden otorgar estrategias de negocio para maximizar ganancias o asegurar ventas a largo plazo, es decir pasar de algo numerico a estrategias y ventajas competitivas en nuestro mercado.
El análisis se estructura en torno a las siguientes preguntas de negocio:
-Desempeño de Ventas:
¿Cómo se comportan las ventas totales y las unidades vendidas por región y producto?
¿Existen diferencias relevantes por método de venta y distribuidor?
-Rentabilidad:
¿Cómo se distribuyen la utilidad operativa y el margen operativo por producto y región?
¿Cuáles son los segmentos más rentables?
-Relación entre Variables:
¿Qué relación existe entre el precio por unidad y las unidades vendidas?
¿Qué relación existe entre las ventas totales y la utilidad operativa?
-Prediccion:
¿Qué combinaciones (producto-región o producto-método de venta) parecen más estratégicas para la compañía?
El análisis exploratorio de datos es un paso fundamental para comprender la estructura, las características y los patrones en los datos de ventas de Adidas..
# Cargar librerías necesarias
library(readxl) # Para leer archivos Excel
library(dplyr) # Para manipulación y transformación de datos
library(ggplot2) # Para creación de gráficos estáticos
library(plotly) # Para gráficos interactivos (basado en ggplot2)
library(knitr) # Para mejorar la presentación de tablas en R Markdown
library(kableExtra) # Para dar formato adicional a las tablas
library(tidyr) # Para ordenar y limpiar datos (útil para pivotar tablas)
datos_adidas <- read_excel("C:/Users/juanj/OneDrive/Escritorio/Ahi/Analitica de datos/Caso 1 - Adidas/DatosCaso1.xlsx")
# Mostrar las primeras filas del dataset para verificar la carga
head(datos_adidas)
| distribuidor | region | estado | ciudad | producto | precio_unidad | unidades_vendidas | ventas_total | utilidad_operativa | margen_operativo | metodo_venta |
|---|---|---|---|---|---|---|---|---|---|---|
| Foot Locker | Northeast | New York | New York | Men’s Street Footwear | 50 | 1200 | 60000 | 30000.0 | 0.50 | In-store |
| Foot Locker | Northeast | New York | New York | Men’s Athletic Footwear | 50 | 1000 | 50000 | 15000.0 | 0.30 | In-store |
| Foot Locker | Northeast | New York | New York | Women’s Street Footwear | 40 | 1000 | 40000 | 14000.0 | 0.35 | In-store |
| Foot Locker | Northeast | New York | New York | Women’s Athletic Footwear | 45 | 850 | 38250 | 13387.5 | 0.35 | In-store |
| Foot Locker | Northeast | New York | New York | Men’s Apparel | 60 | 900 | 54000 | 16200.0 | 0.30 | In-store |
| Foot Locker | Northeast | New York | New York | Women’s Apparel | 50 | 1000 | 50000 | 12500.0 | 0.25 | In-store |
# --- CONTADOR DE REGISTROS ELIMINADOS ---
# Guardamos el número de registros original
registros_iniciales <- nrow(datos_adidas)
# Identificamos cuántos tienen ventas = 0 o unidades = 0
registros_cero_ventas <- sum(datos_adidas$ventas_totales == 0, na.rm = TRUE)
registros_cero_unidades <- sum(datos_adidas$unidades_vendidas == 0, na.rm = TRUE)
registros_cero_ambos <- sum(datos_adidas$ventas_totales == 0 & datos_adidas$unidades_vendidas == 0, na.rm = TRUE)
# Mostramos la información antes de filtrar
cat("========================================\n")
## ========================================
cat("INFORMACIÓN DE FILTRADO DE DATOS\n")
## INFORMACIÓN DE FILTRADO DE DATOS
cat("========================================\n")
## ========================================
cat("Registros iniciales:", registros_iniciales, "\n")
## Registros iniciales: 9648
cat("Registros con ventas = 0:", registros_cero_ventas, "\n")
## Registros con ventas = 0: 0
cat("Registros con unidades = 0:", registros_cero_unidades, "\n")
## Registros con unidades = 0: 4
cat("Registros con ambos = 0:", registros_cero_ambos, "\n")
## Registros con ambos = 0: 0
cat("----------------------------------------\n")
## ----------------------------------------
# --- LIMPIEZA DE DATOS ---
datos_adidas <- datos_adidas %>%
rename(
distribuidor = distribuidor,
region = region,
estado = estado,
ciudad = ciudad,
producto = producto,
precio_unidad = precio_unidad,
unidades_vendidas = unidades_vendidas,
ventas_totales = ventas_total, # Nota: en el excel la columna se llama 'ventas_total'
utilidad_operativa = utilidad_operativa,
margen_operativo = margen_operativo,
metodo_venta = metodo_venta
) %>%
# Filtrar registros con ventas totales = 0 O unidades vendidas = 0
filter(ventas_totales > 0 & unidades_vendidas > 0) %>%
# Convertir a factor las variables categóricas
mutate(
region = as.factor(region),
producto = as.factor(producto),
distribuidor = as.factor(distribuidor),
metodo_venta = as.factor(metodo_venta)
)
# --- MOSTRAR RESULTADO DEL FILTRADO ---
registros_finales <- nrow(datos_adidas)
registros_eliminados <- registros_iniciales - registros_finales
cat("Registros después del filtro:", registros_finales, "\n")
## Registros después del filtro: 9644
cat("Registros eliminados:", registros_eliminados, "\n")
## Registros eliminados: 4
cat("Porcentaje eliminado:", round(registros_eliminados / registros_iniciales * 100, 1), "%\n")
## Porcentaje eliminado: 0 %
cat("========================================\n")
## ========================================
# Verificamos los cambios
glimpse(datos_adidas)
## Rows: 9,644
## Columns: 11
## $ distribuidor <fct> Foot Locker, Foot Locker, Foot Locker, Foot Locker,…
## $ region <fct> Northeast, Northeast, Northeast, Northeast, Northea…
## $ estado <chr> "New York", "New York", "New York", "New York", "Ne…
## $ ciudad <chr> "New York", "New York", "New York", "New York", "Ne…
## $ producto <fct> Men's Street Footwear, Men's Athletic Footwear, Wom…
## $ precio_unidad <dbl> 50, 50, 40, 45, 60, 50, 50, 50, 40, 45, 60, 50, 50,…
## $ unidades_vendidas <dbl> 1200, 1000, 1000, 850, 900, 1000, 1250, 900, 950, 8…
## $ ventas_totales <dbl> 60000, 50000, 40000, 38250, 54000, 50000, 62500, 45…
## $ utilidad_operativa <dbl> 30000.00, 15000.00, 14000.00, 13387.50, 16200.00, 1…
## $ margen_operativo <dbl> 0.50, 0.30, 0.35, 0.35, 0.30, 0.25, 0.50, 0.30, 0.3…
## $ metodo_venta <fct> In-store, In-store, In-store, In-store, In-store, I…
Primero es importante entender a nivel general cómo se comportan las ventas totales y las unidades vendidas en diferentes segmentos. Utilizaremos medidas de tendencia central agrupadas por región y producto y por método de venta y distribuidor para dar con este comportamiento.
# Cargar librerías necesarias
library(scales)
library(kableExtra)
library(dplyr)
library(ggplot2)
library(plotly)
# --- TABLA 1.1: Totales por Región-Producto ---
totales_region_producto <- datos_adidas %>%
group_by(region, producto) %>%
summarise(
ventas_totales = sum(ventas_totales),
unidades_totales = sum(unidades_vendidas),
transacciones = n(),
.groups = "drop"
) %>%
group_by(region) %>%
mutate(
participacion_en_region = ventas_totales / sum(ventas_totales)
) %>%
ungroup() %>%
mutate(
ventas_totales_formato = dollar(ventas_totales, accuracy = 1),
unidades_totales_formato = comma(unidades_totales, accuracy = 1),
participacion_en_region = percent(participacion_en_region, accuracy = 0.1)
) %>%
arrange(region, desc(ventas_totales)) %>%
select(region, producto, ventas_totales_formato, unidades_totales_formato,
transacciones, participacion_en_region)
kable(totales_region_producto,
col.names = c("Region", "Producto", "Ventas Totales", "Unidades Totales",
"Transacciones", "% en Region"),
caption = "Tabla 1.1: Ventas Totales por Region y Producto") %>%
kable_styling(font_size = 11, full_width = FALSE)
| Region | Producto | Ventas Totales | Unidades Totales | Transacciones | % en Region |
|---|---|---|---|---|---|
| Midwest | Men’s Street Footwear | $4,707,360 | 109,861 | 312 | 28.2% |
| Midwest | Women’s Apparel | $3,453,008 | 69,435 | 312 | 20.7% |
| Midwest | Men’s Athletic Footwear | $2,619,289 | 65,120 | 312 | 15.7% |
| Midwest | Men’s Apparel | $2,223,786 | 45,304 | 312 | 13.3% |
| Midwest | Women’s Street Footwear | $1,997,448 | 56,809 | 312 | 12.0% |
| Midwest | Women’s Athletic Footwear | $1,673,543 | 44,808 | 308 | 10.0% |
| Northeast | Men’s Street Footwear | $6,841,324 | 134,252 | 396 | 27.3% |
| Northeast | Women’s Apparel | $5,045,208 | 90,048 | 396 | 20.1% |
| Northeast | Men’s Athletic Footwear | $3,895,862 | 81,474 | 396 | 15.5% |
| Northeast | Men’s Apparel | $3,475,037 | 62,031 | 396 | 13.9% |
| Northeast | Women’s Street Footwear | $3,152,823 | 74,010 | 396 | 12.6% |
| Northeast | Women’s Athletic Footwear | $2,668,013 | 59,464 | 396 | 10.6% |
| South | Women’s Apparel | $4,224,937 | 88,740 | 288 | 20.5% |
| South | Men’s Street Footwear | $4,048,261 | 106,545 | 288 | 19.6% |
| South | Men’s Athletic Footwear | $3,647,045 | 90,079 | 288 | 17.7% |
| South | Women’s Street Footwear | $3,242,822 | 82,257 | 288 | 15.7% |
| South | Men’s Apparel | $2,811,194 | 60,641 | 288 | 13.6% |
| South | Women’s Athletic Footwear | $2,629,097 | 63,998 | 288 | 12.8% |
| Southeast | Men’s Street Footwear | $4,693,836 | 91,867 | 204 | 22.0% |
| Southeast | Women’s Apparel | $4,109,786 | 68,839 | 204 | 19.2% |
| Southeast | Men’s Athletic Footwear | $3,653,645 | 71,129 | 204 | 17.1% |
| Southeast | Men’s Apparel | $3,183,237 | 54,385 | 204 | 14.9% |
| Southeast | Women’s Street Footwear | $3,059,884 | 65,488 | 204 | 14.3% |
| Southeast | Women’s Athletic Footwear | $2,674,048 | 55,292 | 204 | 12.5% |
| West | Men’s Street Footwear | $7,389,988 | 150,795 | 410 | 20.3% |
| West | Women’s Apparel | $7,038,046 | 116,765 | 408 | 19.3% |
| West | Men’s Athletic Footwear | $6,761,339 | 127,724 | 410 | 18.6% |
| West | Women’s Street Footwear | $5,748,586 | 113,705 | 408 | 15.8% |
| West | Men’s Apparel | $4,827,378 | 84,322 | 406 | 13.2% |
| West | Women’s Athletic Footwear | $4,670,820 | 93,674 | 406 | 12.8% |
# --- TABLA 1.2: (ELIMINADA) ---
# --- TABLA 1.3: Resumen por Region ---
resumen_region <- datos_adidas %>%
group_by(region) %>%
summarise(
ventas_totales = sum(ventas_totales),
unidades_totales = sum(unidades_vendidas),
transacciones = n(),
unidades_promedio_x_transaccion = mean(unidades_vendidas),
.groups = "drop"
) %>%
mutate(
participacion_ventas = ventas_totales / sum(datos_adidas$ventas_totales),
participacion_unidades = unidades_totales / sum(datos_adidas$unidades_vendidas)
) %>%
mutate(
ventas_totales = dollar(ventas_totales, accuracy = 1),
unidades_totales = comma(unidades_totales, accuracy = 1),
transacciones = comma(transacciones, accuracy = 1),
unidades_promedio_x_transaccion = round(unidades_promedio_x_transaccion, 1),
participacion_ventas = percent(participacion_ventas, accuracy = 0.1),
participacion_unidades = percent(participacion_unidades, accuracy = 0.1)
) %>%
arrange(desc(ventas_totales))
kable(resumen_region,
col.names = c("Region", "Ventas Totales", "Unidades Totales",
"Transacciones", "Unidades x Transaccion", "% Ventas", "% Unidades"),
caption = "Tabla 1.3: Resumen General por Region") %>%
kable_styling(font_size = 11, full_width = FALSE)
| Region | Ventas Totales | Unidades Totales | Transacciones | Unidades x Transaccion | % Ventas | % Unidades |
|---|---|---|---|---|---|---|
| West | $36,436,157 | 686,985 | 2,448 | 280.6 | 30.3% | 27.7% |
| Northeast | $25,078,267 | 501,279 | 2,376 | 211.0 | 20.9% | 20.2% |
| Southeast | $21,374,436 | 407,000 | 1,224 | 332.5 | 17.8% | 16.4% |
| South | $20,603,356 | 492,260 | 1,728 | 284.9 | 17.1% | 19.9% |
| Midwest | $16,674,434 | 391,337 | 1,868 | 209.5 | 13.9% | 15.8% |
# --- TABLA 1.4: Resumen por Producto ---
resumen_producto <- datos_adidas %>%
group_by(producto) %>%
summarise(
ventas_totales = sum(ventas_totales),
unidades_totales = sum(unidades_vendidas),
transacciones = n(),
unidades_promedio_x_transaccion = mean(unidades_vendidas),
.groups = "drop"
) %>%
mutate(
participacion_ventas = ventas_totales / sum(datos_adidas$ventas_totales),
participacion_unidades = unidades_totales / sum(datos_adidas$unidades_vendidas)
) %>%
mutate(
ventas_totales = dollar(ventas_totales, accuracy = 1),
unidades_totales = comma(unidades_totales, accuracy = 1),
transacciones = comma(transacciones, accuracy = 1),
unidades_promedio_x_transaccion = round(unidades_promedio_x_transaccion, 1),
participacion_ventas = percent(participacion_ventas, accuracy = 0.1),
participacion_unidades = percent(participacion_unidades, accuracy = 0.1)
) %>%
arrange(desc(ventas_totales))
kable(resumen_producto,
col.names = c("Producto", "Ventas Totales", "Unidades Totales",
"Transacciones", "Unidades x Transaccion", "% Ventas", "% Unidades"),
caption = "Tabla 1.4: Resumen General por Producto") %>%
kable_styling(font_size = 11, full_width = FALSE)
| Producto | Ventas Totales | Unidades Totales | Transacciones | Unidades x Transaccion | % Ventas | % Unidades |
|---|---|---|---|---|---|---|
| Men’s Street Footwear | $27,680,769 | 593,320 | 1,610 | 368.5 | 23.0% | 23.9% |
| Women’s Apparel | $23,870,985 | 433,827 | 1,608 | 269.8 | 19.9% | 17.5% |
| Men’s Athletic Footwear | $20,577,180 | 435,526 | 1,610 | 270.5 | 17.1% | 17.6% |
| Women’s Street Footwear | $17,201,563 | 392,269 | 1,608 | 243.9 | 14.3% | 15.8% |
| Men’s Apparel | $16,520,632 | 306,683 | 1,606 | 191.0 | 13.7% | 12.4% |
| Women’s Athletic Footwear | $14,315,521 | 317,236 | 1,602 | 198.0 | 11.9% | 12.8% |
# --- PREPARAR DATOS PARA LOS GRAFICOS ---
# --- Grafico 1.1: Top 5 Combinaciones Region-Producto ---
top_5_combinaciones <- datos_adidas %>%
group_by(region, producto) %>%
summarise(
ventas_totales = sum(ventas_totales),
.groups = "drop"
) %>%
mutate(
combinacion = paste0(region, " - ", producto),
ventas_millones = ventas_totales / 1000000,
ventas_formato = dollar(ventas_totales, accuracy = 1)
) %>%
slice_max(ventas_totales, n = 5)
g1_1 <- ggplot(top_5_combinaciones, aes(x = reorder(combinacion, ventas_totales),
y = ventas_millones,
fill = region)) +
geom_col() +
coord_flip() +
geom_text(aes(label = ventas_formato), hjust = -0.1, size = 3) +
scale_y_continuous(labels = dollar_format(suffix = "M"), expand = expansion(mult = c(0, 0.2))) +
labs(title = "Grafico 1.1: Top 5 Combinaciones Region-Producto",
x = "", y = "Ventas Totales (en millones)", fill = "Region") +
theme_minimal() +
theme(legend.position = "bottom",
axis.text.y = element_text(size = 10))
print(g1_1)
# --- Grafico 1.2: Resumen General por Producto ---
top_8_productos <- resumen_producto %>%
mutate(ventas_num = as.numeric(gsub("[\\$,]", "", ventas_totales))) %>%
slice_max(ventas_num, n = 8)
g1_2 <- ggplot(top_8_productos, aes(x = reorder(producto, ventas_num),
y = ventas_num / 1000000,
fill = producto)) +
geom_col() +
coord_flip() +
geom_text(aes(label = dollar(ventas_num, accuracy = 1)), hjust = -0.1, size = 3) +
scale_y_continuous(labels = dollar_format(suffix = "M"), expand = expansion(mult = c(0, 0.2))) +
labs(title = "Grafico 1.2: Resumen General por Producto",
subtitle = "Top 8 productos por ventas totales",
x = "", y = "Ventas Totales (en millones)") +
theme_minimal() +
theme(legend.position = "none",
axis.text.y = element_text(size = 10))
print(g1_2)
# --- Grafico 1.3: Resumen General por Region ---
datos_torta <- datos_adidas %>%
group_by(region) %>%
summarise(
ventas_totales = sum(ventas_totales),
.groups = "drop"
) %>%
mutate(
participacion = ventas_totales / sum(ventas_totales),
porcentaje = percent(participacion, accuracy = 0.1),
ventas_formato = dollar(ventas_totales, accuracy = 1)
)
g1_3 <- ggplot(datos_torta, aes(x = "", y = participacion, fill = region)) +
geom_col(width = 1, color = "white") +
coord_polar(theta = "y") +
geom_text(aes(label = porcentaje),
position = position_stack(vjust = 0.5),
size = 4) +
scale_fill_brewer(palette = "Set3") +
labs(title = "Grafico 1.3: Resumen General por Region",
subtitle = "Distribucion porcentual de las ventas totales",
fill = "Region") +
theme_void() +
theme(legend.position = "bottom")
print(g1_3)
Por Región
West lidera en ventas totales con el 30.3% de participación ($36.4M) y mayor volumen de unidades (686K).
Northeast es el segundo con 20.9% ventas ($25.1M) y 501K unidades, tiene un buen valor por transaccion ya que esta de segundo en ventas totales y cuenta con un menor numero de unidades x transaccion a comparacion de la otras regiones
Southeast es el tercero con un porcentaje de participacion del 17.8% ($21M) y 400k unidades y tiene la mayor cantidad de unidades x transaccion
Si bien Southeast es el tercero con una participacion de 17.8% ventas no esta muy lejos de South con una participacion de 17.1% ventas ($20.6M) con 492K unidades.
Midwest esta en ultimo lugar con una participacion del 13.9% ventas ($16.7M) y 391K unidades
Por Producto
Men’s Street Footwear más vendido con 23% ventas totales ($27.7M).
Women’s Apparel segundo con 19.9% ventas ($23.9M).
Men’s Athletic Footwear tercero 17.1% ($20.6M).
Women’s Street Footwear cuarto 14.3% ($17.2M).
Por Combinación Región-Producto
West + Men’s Street Footwear más fuerte: $7.4M (20.3% West).
West + Women’s Apparel segunda: $7M (19.3% West).
Northeast + Men’s Street Footwear tercera: $6.8M (27.3% Northeast).
West + Men’s Athletic Footwear cuarta: $6.8M (18.6% West).
West + Women’s Street Footwear quinta: $5.7M (15.8% West).
Men’s Street Footwear top 1-2 en todas las regiones, preferencia consistente.
# Cargar librerías necesarias
library(scales)
library(dplyr)
library(ggplot2)
library(plotly)
library(kableExtra)
# --- TABLA 2: Distribuidor por Metodo de Venta ---
metodo_distribuidor <- datos_adidas %>%
group_by(distribuidor, metodo_venta) %>%
summarise(
ventas_totales = sum(ventas_totales),
unidades_totales = sum(unidades_vendidas),
transacciones = n(),
.groups = "drop"
) %>%
group_by(distribuidor) %>%
mutate(
participacion_en_distribuidor = ventas_totales / sum(ventas_totales)
) %>%
ungroup() %>%
mutate(
ventas_formato = dollar(ventas_totales, accuracy = 1),
unidades_formato = comma(unidades_totales, accuracy = 1),
transacciones_formato = comma(transacciones, accuracy = 1),
participacion_en_distribuidor = percent(participacion_en_distribuidor, accuracy = 0.1)
) %>%
arrange(distribuidor, desc(ventas_totales))
# Mostrar tabla completa
kable(metodo_distribuidor %>%
select(distribuidor, metodo_venta, ventas_formato, unidades_formato,
transacciones_formato, participacion_en_distribuidor),
col.names = c("Distribuidor", "Metodo Venta", "Ventas Totales",
"Unidades Totales", "Transacciones", "% en Distribuidor"),
caption = "Tabla 2: Desempeno por Distribuidor y Metodo de Venta") %>%
kable_styling(font_size = 11, full_width = FALSE)
| Distribuidor | Metodo Venta | Ventas Totales | Unidades Totales | Transacciones | % en Distribuidor |
|---|---|---|---|---|---|
| Amazon | Online | $4,647,981 | 97,859 | 540 | 46.0% |
| Amazon | Outlet | $3,212,381 | 60,081 | 291 | 31.8% |
| Amazon | In-store | $2,236,625 | 40,050 | 118 | 22.2% |
| Foot Locker | Online | $12,233,565 | 258,150 | 1,393 | 42.1% |
| Foot Locker | Outlet | $9,138,880 | 185,474 | 791 | 31.5% |
| Foot Locker | In-store | $7,652,500 | 160,745 | 449 | 26.4% |
| Kohl’s | Online | $5,396,679 | 112,721 | 576 | 39.9% |
| Kohl’s | Outlet | $5,159,149 | 111,284 | 310 | 38.2% |
| Kohl’s | In-store | $2,956,625 | 63,370 | 144 | 21.9% |
| Sports Direct | Online | $10,013,772 | 216,897 | 995 | 40.7% |
| Sports Direct | Outlet | $9,098,000 | 229,373 | 744 | 37.0% |
| Sports Direct | In-store | $5,504,850 | 111,370 | 293 | 22.4% |
| Walmart | Outlet | $5,695,266 | 116,904 | 301 | 54.2% |
| Walmart | Online | $3,169,694 | 68,621 | 288 | 30.2% |
| Walmart | In-store | $1,641,125 | 20,700 | 37 | 15.6% |
| West Gear | In-store | $15,672,650 | 293,755 | 699 | 48.4% |
| West Gear | Online | $9,503,966 | 184,845 | 1,095 | 29.3% |
| West Gear | Outlet | $7,232,942 | 146,662 | 580 | 22.3% |
# --- GRAFICO 2: Ventas por Distribuidor y Metodo de Venta ---
# Preparar datos para el grafico (top 5 distribuidores para no saturar)
top_distribuidores <- metodo_distribuidor %>%
group_by(distribuidor) %>%
summarise(total_dist = sum(ventas_totales), .groups = "drop") %>%
slice_max(total_dist, n = 5) %>%
pull(distribuidor)
datos_grafico <- metodo_distribuidor %>%
filter(distribuidor %in% top_distribuidores) %>%
mutate(
ventas_millones = ventas_totales / 1000000,
# Crear una versión abreviada del nombre para las etiquetas en el eje
distribuidor_corto = case_when(
distribuidor == "Foot Locker" ~ "Foot Locker",
distribuidor == "Sports Direct" ~ "Sports Direct",
distribuidor == "Walmart" ~ "Walmart",
distribuidor == "West Gear" ~ "West Gear",
distribuidor == "Amazon" ~ "Amazon",
distribuidor == "Kohl's" ~ "Kohl's",
TRUE ~ distribuidor
),
etiqueta_hover = paste0("Distribuidor: ", distribuidor, "\n",
"Metodo: ", metodo_venta, "\n",
"Ventas: ", ventas_formato, "\n",
"Unidades: ", unidades_formato, "\n",
"Transacciones: ", transacciones_formato, "\n",
"Participacion: ", participacion_en_distribuidor)
)
# Grafico de barras agrupadas con nombres mejorados
g2 <- ggplot(datos_grafico, aes(x = reorder(distribuidor_corto, -ventas_totales),
y = ventas_millones,
fill = metodo_venta,
text = etiqueta_hover)) +
geom_col(position = "dodge", width = 0.7) +
geom_text(aes(label = participacion_en_distribuidor),
position = position_dodge(width = 0.7),
vjust = -0.5, size = 3, fontface = "bold") +
scale_y_continuous(labels = dollar_format(suffix = "M"),
expand = expansion(mult = c(0, 0.15))) +
scale_fill_brewer(palette = "Set2") +
labs(title = "Grafico 2: Ventas por Distribuidor y Metodo de Venta",
subtitle = "Top 5 distribuidores (etiquetas = % dentro del distribuidor)",
x = "Distribuidor", y = "Ventas Totales (en millones)",
fill = "Metodo de Venta") +
theme_minimal() +
theme(
plot.title = element_text(face = "bold", size = 16, color = "#2C3E50"),
plot.subtitle = element_text(size = 12, color = "#7F8C8D"),
axis.text.x = element_text(angle = 0, hjust = 0.5, size = 11, face = "bold"),
axis.text.y = element_text(size = 10),
legend.position = "bottom",
legend.text = element_text(size = 9),
panel.grid.major.x = element_blank(),
plot.background = element_rect(fill = "#F8F9FA", color = NA)
)
# Convertir a plotly interactivo
g2_interactivo <- ggplotly(g2, tooltip = "text") %>%
layout(hoverlabel = list(bgcolor = "white",
font = list(size = 12, color = "#2C3E50")),
xaxis = list(tickangle = 0))
# Mostrar grafico
g2_interactivo
# --- VERSION ALTERNATIVA: Grafico 2 con nombres en vertical ---
g2_vertical <- ggplot(datos_grafico, aes(x = reorder(distribuidor_corto, -ventas_totales),
y = ventas_millones,
fill = metodo_venta,
text = etiqueta_hover)) +
geom_col(position = "dodge", width = 0.7) +
geom_text(aes(label = participacion_en_distribuidor),
position = position_dodge(width = 0.7),
vjust = -0.5, size = 3, fontface = "bold") +
scale_y_continuous(labels = dollar_format(suffix = "M"),
expand = expansion(mult = c(0, 0.15))) +
scale_fill_brewer(palette = "Set2") +
labs(title = "Grafico 2: Ventas por Distribuidor y Metodo de Venta",
subtitle = "Top 5 distribuidores (etiquetas = % dentro del distribuidor)",
x = "Distribuidor", y = "Ventas Totales (en millones)",
fill = "Metodo de Venta") +
theme_minimal() +
theme(
plot.title = element_text(face = "bold", size = 16, color = "#2C3E50"),
plot.subtitle = element_text(size = 12, color = "#7F8C8D"),
axis.text.x = element_text(angle = 45, hjust = 1, size = 11, face = "bold"),
axis.text.y = element_text(size = 10),
legend.position = "bottom",
legend.text = element_text(size = 9),
panel.grid.major.x = element_blank(),
plot.background = element_rect(fill = "#F8F9FA", color = NA)
)
# Convertir a plotly interactivo
g2_vertical_interactivo <- ggplotly(g2_vertical, tooltip = "text") %>%
layout(hoverlabel = list(bgcolor = "white",
font = list(size = 12, color = "#2C3E50")),
xaxis = list(tickangle = 45))
# Mostrar version alternativa si es necesario
# g2_vertical_interactivo
West Gear In-store: $15.7M (48% de ventas de West Gear) Domina el mercado fisico de primera mano
Foot Locker Online: $12.2M (42% Foot Locker) Dominan las compras online
Sports Direct Online: $10M (41% Sports Direct) Dominan las compras online
West Gear Online: $9.5M (29% West Gear) Omnicanal con fuerte presencia
Foot Locker Outlet: $9.1M (32% Foot Locker) Descuentos rentables
Patrón Clave: Online es el canal mas relevante a lo largo de todos los distribuidores
En esta instancia ya se empieza a ver una tendencia por el canal online a nivel micro, mas adelante exploraremos si esta tendencia se mantiene a nivel macro
Explorar Rentabilidad es crucial porque ventas altas no garantizan ganancias, por ejemplo productos y regiones con alto volumen pueden tener bajos márgenes. Identificar verdaderos generadores de caja es fundamental para asignar recursos de manera efectiva
# Cargar librerías necesarias
library(scales)
library(dplyr)
library(ggplot2)
library(plotly)
library(kableExtra)
library(tidyr)
# --- ANALISIS DE RENTABILIDAD POR PRODUCTO Y REGION ---
# ============================================================
# TABLA 3.1 Y GRAFICO 3.1: Rentabilidad por Producto
# ============================================================
# --- TABLA 3.1: Resumen de Rentabilidad por Producto ---
rentabilidad_producto <- datos_adidas %>%
group_by(producto) %>%
summarise(
ventas_totales = sum(ventas_totales),
utilidad_total = sum(utilidad_operativa),
margen_promedio = mean(margen_operativo),
margen_ponderado = utilidad_total / ventas_totales,
transacciones = n(),
.groups = "drop"
) %>%
mutate(
participacion_ventas = ventas_totales / sum(ventas_totales),
participacion_utilidad = utilidad_total / sum(utilidad_total)
) %>%
arrange(desc(utilidad_total))
# Calcular totales (solo para referencia)
totales_producto <- rentabilidad_producto %>%
summarise(
producto = "TOTAL",
ventas_totales = NA,
utilidad_total = NA,
margen_promedio = NA,
margen_ponderado = NA,
transacciones = NA,
participacion_ventas = 1,
participacion_utilidad = 1
)
# Unir y formatear
rentabilidad_producto_completa <- bind_rows(rentabilidad_producto, totales_producto) %>%
mutate(
ventas_formato = ifelse(is.na(ventas_totales), "-", dollar(ventas_totales, accuracy = 1)),
utilidad_formato = ifelse(is.na(utilidad_total), "-", dollar(utilidad_total, accuracy = 1)),
margen_promedio = ifelse(is.na(margen_promedio), "-", percent(margen_promedio, accuracy = 0.1)),
margen_ponderado = ifelse(is.na(margen_ponderado), "-", percent(margen_ponderado, accuracy = 0.1)),
transacciones = ifelse(is.na(transacciones), "-", comma(transacciones, accuracy = 1)),
participacion_ventas = ifelse(producto == "TOTAL", "100%", percent(participacion_ventas, accuracy = 0.1)),
participacion_utilidad = ifelse(producto == "TOTAL", "100%", percent(participacion_utilidad, accuracy = 0.1))
) %>%
select(producto, ventas_formato, utilidad_formato, margen_promedio,
margen_ponderado, transacciones, participacion_ventas, participacion_utilidad)
# Mostrar Tabla 3.1
kable(rentabilidad_producto_completa,
col.names = c("Producto", "Ventas Totales", "Utilidad Total",
"Margen Promedio", "Margen Ponderado", "Transacciones",
"% Ventas", "% Utilidad"),
caption = "Tabla 3.1: Rentabilidad por Producto") %>%
kable_styling(font_size = 11, full_width = FALSE) %>%
row_spec(nrow(rentabilidad_producto_completa), bold = TRUE, background = "#F0F0F0")
| Producto | Ventas Totales | Utilidad Total | Margen Promedio | Margen Ponderado | Transacciones | % Ventas | % Utilidad |
|---|---|---|---|---|---|---|---|
| Men’s Street Footwear | $27,680,769 | $11,629,046 | 44.6% | 42.0% | 1,610 | 23.0% | 24.6% |
| Women’s Apparel | $23,870,985 | $9,685,221 | 44.1% | 40.6% | 1,608 | 19.9% | 20.5% |
| Men’s Athletic Footwear | $20,577,180 | $7,437,457 | 40.3% | 36.1% | 1,610 | 17.1% | 15.7% |
| Women’s Street Footwear | $17,201,563 | $6,494,017 | 41.0% | 37.8% | 1,608 | 14.3% | 13.8% |
| Men’s Apparel | $16,520,632 | $6,381,405 | 41.3% | 38.6% | 1,606 | 13.7% | 13.5% |
| Women’s Athletic Footwear | $14,315,521 | $5,597,822 | 42.4% | 39.1% | 1,602 | 11.9% | 11.9% |
| TOTAL |
|
|
|
|
|
100% | 100% |
# --- Grafico 3.1: Margen y Ventas por Producto ---
productos_grafico <- rentabilidad_producto %>%
mutate(
ventas_millones = ventas_totales / 1000000,
margen_num = round(margen_ponderado * 100, 1), # Redondear a 1 decimal
etiqueta = paste0(producto, "\n", margen_num, "%")
) %>%
slice_max(ventas_totales, n = 8)
g3_1 <- ggplot(productos_grafico, aes(x = reorder(producto, ventas_totales),
y = ventas_millones,
fill = margen_num)) +
geom_col() +
coord_flip() +
geom_text(aes(label = dollar(ventas_totales, accuracy = 1)), hjust = -0.1, size = 3) +
scale_fill_gradient(low = "lightcoral", high = "darkgreen", name = "Margen %") +
scale_y_continuous(labels = dollar_format(suffix = "M"), expand = expansion(mult = c(0, 0.2))) +
labs(title = "Grafico 3.1: Top 8 Productos por Ventas y Margen",
subtitle = "Color indica margen de utilidad (verde = alto margen)",
x = "", y = "Ventas Totales (en millones)") +
theme_minimal() +
theme(legend.position = "bottom",
axis.text.y = element_text(size = 10))
print(g3_1)
# ============================================================
# TABLA 3.2 Y GRAFICO 3.2: Rentabilidad por Region
# ============================================================
# --- TABLA 3.2: Resumen de Rentabilidad por Region ---
rentabilidad_region <- datos_adidas %>%
group_by(region) %>%
summarise(
ventas_totales = sum(ventas_totales),
utilidad_total = sum(utilidad_operativa),
margen_promedio = mean(margen_operativo),
margen_ponderado = utilidad_total / ventas_totales,
transacciones = n(),
.groups = "drop"
) %>%
mutate(
participacion_ventas = ventas_totales / sum(ventas_totales),
participacion_utilidad = utilidad_total / sum(utilidad_total)
) %>%
arrange(desc(utilidad_total))
# Calcular totales (solo para referencia)
totales_region <- rentabilidad_region %>%
summarise(
region = "TOTAL",
ventas_totales = NA,
utilidad_total = NA,
margen_promedio = NA,
margen_ponderado = NA,
transacciones = NA,
participacion_ventas = 1,
participacion_utilidad = 1
)
# Unir y formatear
rentabilidad_region_completa <- bind_rows(rentabilidad_region, totales_region) %>%
mutate(
ventas_formato = ifelse(is.na(ventas_totales), "-", dollar(ventas_totales, accuracy = 1)),
utilidad_formato = ifelse(is.na(utilidad_total), "-", dollar(utilidad_total, accuracy = 1)),
margen_promedio = ifelse(is.na(margen_promedio), "-", percent(margen_promedio, accuracy = 0.1)),
margen_ponderado = ifelse(is.na(margen_ponderado), "-", percent(margen_ponderado, accuracy = 0.1)),
transacciones = ifelse(is.na(transacciones), "-", comma(transacciones, accuracy = 1)),
participacion_ventas = ifelse(region == "TOTAL", "100%", percent(participacion_ventas, accuracy = 0.1)),
participacion_utilidad = ifelse(region == "TOTAL", "100%", percent(participacion_utilidad, accuracy = 0.1))
) %>%
select(region, ventas_formato, utilidad_formato, margen_promedio,
margen_ponderado, transacciones, participacion_ventas, participacion_utilidad)
# Mostrar Tabla 3.2
kable(rentabilidad_region_completa,
col.names = c("Region", "Ventas Totales", "Utilidad Total",
"Margen Promedio", "Margen Ponderado", "Transacciones",
"% Ventas", "% Utilidad"),
caption = "Tabla 3.2: Rentabilidad por Region") %>%
kable_styling(font_size = 11, full_width = FALSE) %>%
row_spec(nrow(rentabilidad_region_completa), bold = TRUE, background = "#F0F0F0")
| Region | Ventas Totales | Utilidad Total | Margen Promedio | Margen Ponderado | Transacciones | % Ventas | % Utilidad |
|---|---|---|---|---|---|---|---|
| West | $36,436,157 | $13,017,584 | 39.7% | 35.7% | 2,448 | 30.3% | 27.6% |
| Northeast | $25,078,267 | $9,732,774 | 41.0% | 38.8% | 2,376 | 20.9% | 20.6% |
| South | $20,603,356 | $9,221,605 | 46.7% | 44.8% | 1,728 | 17.1% | 19.5% |
| Southeast | $21,374,436 | $8,393,059 | 41.9% | 39.3% | 1,224 | 17.8% | 17.8% |
| Midwest | $16,674,434 | $6,859,945 | 43.5% | 41.1% | 1,868 | 13.9% | 14.5% |
| TOTAL |
|
|
|
|
|
100% | 100% |
# --- Grafico 3.2: Margen por Region (Barras) ---
regiones_grafico <- rentabilidad_region %>%
mutate(
ventas_millones = ventas_totales / 1000000,
margen_num = round(margen_ponderado * 100, 1), # REDONDEADO a 1 decimal
region = factor(region, levels = region[order(ventas_totales, decreasing = TRUE)])
)
g3_2 <- ggplot(regiones_grafico, aes(x = region, y = margen_num, fill = region)) +
geom_col() +
geom_text(aes(label = paste0(margen_num, "%")), vjust = -0.5, size = 4) + # Etiqueta con 1 decimal
scale_y_continuous(limits = c(0, max(regiones_grafico$margen_num) * 1.1)) +
labs(title = "Grafico 3.2: Margen de Utilidad por Region",
subtitle = "Regiones ordenadas de mayor a menor ventas (izquierda a derecha)",
x = "Region", y = "Margen de Utilidad (%)") +
theme_minimal() +
theme(legend.position = "none",
axis.text.x = element_text(angle = 45, hjust = 1))
print(g3_2)
# ============================================================
# TABLA 3.3 Y GRAFICO 3.3: Rentabilidad por Combinacion Region-Producto
# ============================================================
# --- TABLA 3.3: Rentabilidad por Combinacion Region-Producto ---
rentabilidad_region_producto <- datos_adidas %>%
group_by(region, producto) %>%
summarise(
ventas_totales = sum(ventas_totales),
utilidad_total = sum(utilidad_operativa),
margen_promedio = mean(margen_operativo),
margen_ponderado = utilidad_total / ventas_totales,
transacciones = n(),
.groups = "drop"
) %>%
mutate(
participacion_ventas_global = ventas_totales / sum(ventas_totales),
participacion_utilidad_global = utilidad_total / sum(utilidad_total)
) %>%
arrange(desc(utilidad_total))
# Calcular totales para la tabla 3.3
totales_rp <- rentabilidad_region_producto %>%
summarise(
region = "TOTAL",
producto = "",
ventas_totales = NA,
utilidad_total = NA,
margen_promedio = NA,
margen_ponderado = NA,
transacciones = NA,
participacion_ventas_global = 1,
participacion_utilidad_global = 1
)
# Formatear tabla 3.3 (top 20 + totales)
rentabilidad_rp_top20 <- rentabilidad_region_producto %>%
head(20) %>%
mutate(
ventas_formato = dollar(ventas_totales, accuracy = 1),
utilidad_formato = dollar(utilidad_total, accuracy = 1),
margen_promedio = percent(margen_promedio, accuracy = 0.1),
margen_ponderado = percent(margen_ponderado, accuracy = 0.1),
transacciones = comma(transacciones, accuracy = 1),
participacion_ventas_global = percent(participacion_ventas_global, accuracy = 0.1),
participacion_utilidad_global = percent(participacion_utilidad_global, accuracy = 0.1)
) %>%
select(region, producto, ventas_formato, utilidad_formato, margen_ponderado,
transacciones, participacion_ventas_global, participacion_utilidad_global)
# Formatear totales
totales_rp_formateado <- totales_rp %>%
mutate(
ventas_formato = "-",
utilidad_formato = "-",
margen_promedio = "-",
margen_ponderado = "-",
transacciones = "-",
participacion_ventas_global = "100%",
participacion_utilidad_global = "100%"
) %>%
select(region, producto, ventas_formato, utilidad_formato, margen_ponderado,
transacciones, participacion_ventas_global, participacion_utilidad_global)
# Unir y mostrar
rentabilidad_rp_final <- bind_rows(rentabilidad_rp_top20, totales_rp_formateado)
kable(rentabilidad_rp_final,
col.names = c("Region", "Producto", "Ventas Totales", "Utilidad Total",
"Margen", "Transacciones", "% Ventas Global", "% Utilidad Global"),
caption = "Tabla 3.3: Top 20 Combinaciones Region-Producto (con totales solo en %)") %>%
kable_styling(font_size = 11, full_width = FALSE) %>%
row_spec(nrow(rentabilidad_rp_final), bold = TRUE, background = "#F0F0F0")
| Region | Producto | Ventas Totales | Utilidad Total | Margen | Transacciones | % Ventas Global | % Utilidad Global |
|---|---|---|---|---|---|---|---|
| Northeast | Men’s Street Footwear | $6,841,324 | $3,030,663 | 44.3% | 396 | 5.7% | 6.4% |
| West | Men’s Street Footwear | $7,389,988 | $2,907,503 | 39.3% | 410 | 6.1% | 6.2% |
| South | Women’s Apparel | $4,224,937 | $2,199,137 | 52.1% | 288 | 3.5% | 4.7% |
| West | Men’s Athletic Footwear | $6,761,339 | $2,154,211 | 31.9% | 410 | 5.6% | 4.6% |
| West | Women’s Street Footwear | $5,748,586 | $2,142,439 | 37.3% | 408 | 4.8% | 4.5% |
| West | Women’s Apparel | $7,038,046 | $2,096,258 | 29.8% | 408 | 5.9% | 4.4% |
| West | Men’s Apparel | $4,827,378 | $2,009,555 | 41.6% | 406 | 4.0% | 4.3% |
| Southeast | Men’s Street Footwear | $4,693,836 | $2,003,886 | 42.7% | 204 | 3.9% | 4.2% |
| Midwest | Men’s Street Footwear | $4,707,360 | $1,948,621 | 41.4% | 312 | 3.9% | 4.1% |
| Northeast | Women’s Apparel | $5,045,208 | $1,917,008 | 38.0% | 396 | 4.2% | 4.1% |
| Southeast | Women’s Apparel | $4,109,786 | $1,887,045 | 45.9% | 204 | 3.4% | 4.0% |
| South | Men’s Street Footwear | $4,048,261 | $1,738,372 | 42.9% | 288 | 3.4% | 3.7% |
| West | Women’s Athletic Footwear | $4,670,820 | $1,707,618 | 36.6% | 406 | 3.9% | 3.6% |
| Midwest | Women’s Apparel | $3,453,008 | $1,585,772 | 45.9% | 312 | 2.9% | 3.4% |
| South | Men’s Athletic Footwear | $3,647,045 | $1,504,995 | 41.3% | 288 | 3.0% | 3.2% |
| Northeast | Men’s Athletic Footwear | $3,895,862 | $1,474,713 | 37.9% | 396 | 3.2% | 3.1% |
| South | Women’s Street Footwear | $3,242,822 | $1,398,549 | 43.1% | 288 | 2.7% | 3.0% |
| Southeast | Men’s Athletic Footwear | $3,653,645 | $1,333,467 | 36.5% | 204 | 3.0% | 2.8% |
| South | Women’s Athletic Footwear | $2,629,097 | $1,277,839 | 48.6% | 288 | 2.2% | 2.7% |
| Northeast | Men’s Apparel | $3,475,037 | $1,183,786 | 34.1% | 396 | 2.9% | 2.5% |
| TOTAL |
|
|
|
|
100% | 100% |
# --- Grafico 3.3: Mapa de Calor - Margen por Region y Producto ---
datos_calor_rp <- rentabilidad_region_producto %>%
head(30) %>% # Top 30 combinaciones para no saturar
mutate(
margen_num = round(margen_ponderado * 100, 1), # Redondear a 1 decimal
etiqueta = paste0(margen_num, "%"),
texto_hover = paste0("Region: ", region, "\n",
"Producto: ", producto, "\n",
"Margen: ", margen_num, "%\n",
"Ventas: ", dollar(ventas_totales, accuracy = 1), "\n",
"Utilidad: ", dollar(utilidad_total, accuracy = 1))
)
g3_3 <- ggplot(datos_calor_rp, aes(x = region, y = producto, fill = margen_num,
text = texto_hover)) +
geom_tile() +
geom_text(aes(label = etiqueta), size = 3) +
scale_fill_gradient(low = "white", high = "darkgreen", name = "Margen %") +
labs(title = "Grafico 3.3: Mapa de Calor - Margen por Region y Producto",
subtitle = "Top 30 combinaciones (color mas oscuro = mayor margen)",
x = "Region", y = "Producto") +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, hjust = 1),
axis.text.y = element_text(size = 8))
# Convertir a plotly interactivo
g3_3_interactivo <- ggplotly(g3_3, tooltip = "text") %>%
layout(hoverlabel = list(bgcolor = "white", font = list(size = 11)))
print(g3_3_interactivo)
Por Producto
Men’s Street Footwear: $11.6M de utilidad, 45% margen promedio - Muy rentable
Women’s Apparel: $9.7M de utilidad, 44% margen - Rentable aunque se evidencia una caida en comparacion a Men’s Street Footwear
Men’s Athletic: $7.4M de utilidad, 40% margen - Se evidencia aun mas la caida de rentabilidad en comparacion al producto lider
Por Región
South: 46,7% margen líder, $9.2M - maxima eficiencia
Midwest: 43,5% de margen, $6.9M - Excelente eficiencia
Southeast: 42% de margen , $8.4M
West y Northeast: Si bien no son lideres en terminos de margen promedio frente a las otras regiones, son los que traen una mayor cantidad de utilidad operativa, en gran medida debido a sus grandes volumenes
Se evidencia que no por tener mayor cantidad de ventas se tienen el mayor margen de ganancias, de hecho se evidencia lo contrario donde las regiones donde menos se registran volumenes de ventas son los que mejor margen tienen.
Combinaciones (Región+Producto) - Northeast + Men’s Street: $3M de utilidad y un margen del 44%
West + Men’s Street: $2.9M de utilidad y un margen del 39,3%, muy parecido a la combinacion estrella (posible sustituto)
South + Women’s Apparel: $2.2M de u tilidad y un margen del 52%, en terminos de margen operativo es la mejor combinacion a pesar de representar un bajo porcentaje de las ventas totales 3.5%
Conclusión: Northeast/West Men´s Street Footwear + South Women´s Apparel junta las 3 regiones lideres tanto en ventas como utilidad operacional y junta los 2 productos lideres en utilidades, se identifica una combinacion incial de productos y region efectiva para maximizar ganancias
Esta seccion es fundamental para el caso Adidas porque nos muestra una serie de correlaciones que permiten validar estrategias de precio y optimizar la asignación de recursos hacia aquellos productos y regiones que generen la mayor rentabilidad. Sin esta evidencia cuantitativa, las recomendaciones serían especulativas, con ella, Adidas puede priorizar combinaciones probadas que maximizan la ganancia.
# Cargar librerías necesarias
library(scales)
library(dplyr)
library(ggplot2)
library(plotly)
library(kableExtra)
# --- SECCION: RELACION ENTRE PRECIO Y VOLUMEN DE VENTAS ---
# --- PASO 1: CREAR RANGOS DE PRECIO (5 intervalos con etiquetas numericas) ---
datos_adidas <- datos_adidas %>%
mutate(
rango_precio = case_when(
precio_unidad < 20 ~ "Muy Bajo (< $20)",
precio_unidad >= 20 & precio_unidad < 40 ~ "Bajo ($20 - $40)",
precio_unidad >= 40 & precio_unidad < 60 ~ "Medio ($40 - $60)",
precio_unidad >= 60 & precio_unidad < 80 ~ "Medio-Alto ($60 - $80)",
precio_unidad >= 80 ~ "Alto (>= $80)"
),
rango_precio = factor(rango_precio,
levels = c("Muy Bajo (< $20)",
"Bajo ($20 - $40)",
"Medio ($40 - $60)",
"Medio-Alto ($60 - $80)",
"Alto (>= $80)"))
)
# --- PASO 2: TABLA RESUMEN POR RANGO DE PRECIO ---
tabla_precio <- datos_adidas %>%
group_by(rango_precio) %>%
summarise(
transacciones = n(),
precio_promedio = mean(precio_unidad),
unidades_promedio = mean(unidades_vendidas),
unidades_totales = sum(unidades_vendidas),
ventas_promedio = mean(ventas_totales),
ventas_totales = sum(ventas_totales),
.groups = "drop"
) %>%
mutate(
participacion_ventas = ventas_totales / sum(ventas_totales),
participacion_unidades = unidades_totales / sum(unidades_totales)
)
# --- PASO 3: TABLA FORMATEADA PARA PRESENTACION ---
tabla_precio_formateada <- tabla_precio %>%
mutate(
transacciones = comma(transacciones, accuracy = 1),
precio_promedio = dollar(precio_promedio, accuracy = 0.01),
unidades_promedio = round(unidades_promedio, 1),
unidades_totales = comma(unidades_totales, accuracy = 1),
ventas_promedio = dollar(ventas_promedio, accuracy = 0.01),
ventas_totales = dollar(ventas_totales, accuracy = 1),
participacion_ventas = percent(participacion_ventas, accuracy = 0.1),
participacion_unidades = percent(participacion_unidades, accuracy = 0.1)
) %>%
select(rango_precio, transacciones, precio_promedio, unidades_promedio,
unidades_totales, ventas_promedio, ventas_totales,
participacion_ventas, participacion_unidades)
# --- TABLA 4.1: Comportamiento de Ventas por Rango de Precio ---
kable(tabla_precio_formateada,
col.names = c("Rango de Precio", "Transacciones", "Precio Promedio",
"Unidades x Trans", "Unidades Totales", "Ticket Promedio",
"Ventas Totales", "% Ventas", "% Unidades"),
caption = "Tabla 4.1: Comportamiento de Ventas por Rango de Precio") %>%
kable_styling(font_size = 11, full_width = FALSE) %>%
row_spec(0, bold = TRUE, background = "#F0F0F0")
| Rango de Precio | Transacciones | Precio Promedio | Unidades x Trans | Unidades Totales | Ticket Promedio | Ventas Totales | % Ventas | % Unidades |
|---|---|---|---|---|---|---|---|---|
| Muy Bajo (< $20) | 320 | $15.77 | 148.8 | 47,615 | $2,320.41 | $742,531 | 0.6% | 1.9% |
| Bajo ($20 - $40) | 3,004 | $31.46 | 196.0 | 588,690 | $6,078.96 | $18,261,190 | 15.2% | 23.7% |
| Medio ($40 - $60) | 4,663 | $48.09 | 261.7 | 1,220,465 | $12,600.69 | $58,757,014 | 48.9% | 49.2% |
| Medio-Alto ($60 - $80) | 1,453 | $65.17 | 364.5 | 529,559 | $23,649.56 | $34,362,809 | 28.6% | 21.4% |
| Alto (>= $80) | 204 | $86.54 | 453.6 | 92,532 | $39,426.99 | $8,043,106 | 6.7% | 3.7% |
# --- GRAFICO 4.1: Precio vs Unidades Totales Vendidas ---
g4_1 <- ggplot(tabla_precio, aes(x = rango_precio, y = unidades_totales, fill = rango_precio)) +
geom_col() +
geom_text(aes(label = comma(unidades_totales)), vjust = -0.5, size = 3.5) +
scale_y_continuous(labels = comma_format()) +
labs(title = "Grafico 4.1: Precio vs Unidades Totales Vendidas",
subtitle = "Volumen total de unidades por rango de precio",
x = "Rango de Precio", y = "Unidades Totales Vendidas") +
theme_minimal() +
theme(legend.position = "none", axis.text.x = element_text(angle = 45, hjust = 1))
# --- GRAFICO 4.2: Precio vs Ventas Totales ---
g4_2 <- ggplot(tabla_precio, aes(x = rango_precio, y = ventas_totales, fill = rango_precio)) +
geom_col() +
geom_text(aes(label = dollar(ventas_totales)), vjust = -0.5, size = 3.5) +
scale_y_continuous(labels = dollar_format()) +
labs(title = "Grafico 4.2: Precio vs Ventas Totales",
subtitle = "Ingreso total generado por rango de precio",
x = "Rango de Precio", y = "Ventas Totales") +
theme_minimal() +
theme(legend.position = "none", axis.text.x = element_text(angle = 45, hjust = 1))
# --- GRAFICO 4.3: Precio vs Ticket Promedio ---
g4_3 <- ggplot(tabla_precio, aes(x = rango_precio, y = ventas_promedio, fill = rango_precio)) +
geom_col() +
geom_text(aes(label = dollar(ventas_promedio, accuracy = 1)), vjust = -0.5, size = 3.5) +
scale_y_continuous(labels = dollar_format()) +
labs(title = "Grafico 4.3: Precio vs Ticket Promedio",
subtitle = "Valor promedio por transaccion segun rango de precio",
x = "Rango de Precio", y = "Ticket Promedio") +
theme_minimal() +
theme(legend.position = "none", axis.text.x = element_text(angle = 45, hjust = 1))
# --- GRAFICO 4.4: Precio vs Unidades Promedio ---
g4_4 <- ggplot(tabla_precio, aes(x = rango_precio, y = unidades_promedio, fill = rango_precio)) +
geom_col() +
geom_text(aes(label = round(unidades_promedio, 1)), vjust = -0.5, size = 3.5) +
scale_y_continuous() +
labs(title = "Grafico 4.4: Precio vs Unidades Promedio",
subtitle = "Unidades promedio por transaccion segun rango de precio",
x = "Rango de Precio", y = "Unidades Promedio") +
theme_minimal() +
theme(legend.position = "none", axis.text.x = element_text(angle = 45, hjust = 1))
# --- CONVERTIR GRAFICOS A PLOTLY INTERACTIVO ---
g4_1_int <- ggplotly(g4_1)
g4_2_int <- ggplotly(g4_2)
g4_3_int <- ggplotly(g4_3)
g4_4_int <- ggplotly(g4_4)
# --- MOSTRAR RESULTADOS ---
# Tabla 4.1 ya se mostro arriba
g4_1_int
g4_2_int
g4_3_int
g4_4_int
Dependiendo de si se analiza por el total de ventas o el promedio de ventas, se encuentran 2 cosas totalmente diferentes. Primero, si se observa el Precio vs Unidades Totales (figura 4.1) se observa que los clientes compran en mayor cantidad los productos con precios de rango medio ($40-$60) y que la distribución es muy simétrica, teniendo los productos de rango bajo y rango medio-alto concentraciones muy similares. Ahora si se analiza por el Precio vs Unidades Promedio (figura 4.4) observamos que la distribución sigue el patrón de precio, es decir, entre mayor precio se venden en promedio más unidades, esto se debe a que los clientes que compran en rangos de precio altos compran en promedio mayores cantidades que los clientes que compran en rangos medios. Ahora si observamos Precio vs Ventas Totales (figura 4.2) y Precio vs Ticket Promedio (figura 4.3) logramos ver que se comportan igual que la variable de unidades, este hallazgo resulta relevante porque nos dice que Adidas puede equilibrar rangos de precio medios para volumen y rangos de precio altos para margen de ganancia.
# Cargar librerías necesarias
library(scales)
library(dplyr)
library(ggplot2)
library(plotly)
library(kableExtra)
# --- SECCION: RELACION ENTRE VENTAS TOTALES Y UTILIDAD OPERATIVA ---
# --- PASO 1: CALCULAR ORDEN DE REGIONES POR VENTAS TOTALES ---
orden_regiones <- datos_adidas %>%
group_by(region) %>%
summarise(ventas_totales = sum(ventas_totales), .groups = "drop") %>%
arrange(desc(ventas_totales)) %>%
pull(region)
# ============================================================
# TABLA 5.1: Resumen Global de Ventas y Utilidad
# ============================================================
tabla_global <- datos_adidas %>%
summarise(
ventas_totales = sum(ventas_totales),
utilidad_total = sum(utilidad_operativa),
margen_promedio = mean(margen_operativo),
transacciones = n(),
.groups = "drop"
) %>%
mutate(
ventas_totales = dollar(ventas_totales, accuracy = 1),
utilidad_total = dollar(utilidad_total, accuracy = 1),
margen_promedio = percent(margen_promedio, accuracy = 0.1),
transacciones = comma(transacciones, accuracy = 1)
)
# Mostrar Tabla 5.1
kable(tabla_global,
col.names = c("Ventas Totales", "Utilidad Total", "Margen Promedio", "Transacciones"),
caption = "Tabla 5.1: Resumen Global de Ventas y Utilidad") %>%
kable_styling(font_size = 11, full_width = FALSE) %>%
row_spec(0, bold = TRUE, background = "#F0F0F0")
| Ventas Totales | Utilidad Total | Margen Promedio | Transacciones |
|---|---|---|---|
| $120,166,650 | $47,224,968 | 42.3% | 9,644 |
# ============================================================
# TABLA 5.2: Ventas y Utilidad por Region
# ============================================================
tabla_region <- datos_adidas %>%
group_by(region) %>%
summarise(
ventas_totales = sum(ventas_totales),
utilidad_total = sum(utilidad_operativa),
margen_promedio = mean(margen_operativo),
transacciones = n(),
.groups = "drop"
) %>%
mutate(
participacion_ventas = ventas_totales / sum(ventas_totales),
participacion_utilidad = utilidad_total / sum(utilidad_total),
ventas_totales = dollar(ventas_totales, accuracy = 1),
utilidad_total = dollar(utilidad_total, accuracy = 1),
margen_promedio = percent(margen_promedio, accuracy = 0.1),
transacciones = comma(transacciones, accuracy = 1),
participacion_ventas = percent(participacion_ventas, accuracy = 0.1),
participacion_utilidad = percent(participacion_utilidad, accuracy = 0.1)
) %>%
arrange(match(region, orden_regiones))
# Mostrar Tabla 5.2
kable(tabla_region,
col.names = c("Region", "Ventas Totales", "Utilidad Total", "Margen Promedio",
"Transacciones", "% Ventas", "% Utilidad"),
caption = "Tabla 5.2: Ventas y Utilidad por Region (ordenadas por ventas)") %>%
kable_styling(font_size = 11, full_width = FALSE) %>%
row_spec(0, bold = TRUE, background = "#F0F0F0")
| Region | Ventas Totales | Utilidad Total | Margen Promedio | Transacciones | % Ventas | % Utilidad |
|---|---|---|---|---|---|---|
| West | $36,436,157 | $13,017,584 | 39.7% | 2,448 | 30.3% | 27.6% |
| Northeast | $25,078,267 | $9,732,774 | 41.0% | 2,376 | 20.9% | 20.6% |
| Southeast | $21,374,436 | $8,393,059 | 41.9% | 1,224 | 17.8% | 17.8% |
| South | $20,603,356 | $9,221,605 | 46.7% | 1,728 | 17.1% | 19.5% |
| Midwest | $16,674,434 | $6,859,945 | 43.5% | 1,868 | 13.9% | 14.5% |
# ============================================================
# TABLA 5.3: Ventas y Utilidad por Metodo de Venta
# ============================================================
tabla_metodo <- datos_adidas %>%
group_by(metodo_venta) %>%
summarise(
ventas_totales = sum(ventas_totales),
utilidad_total = sum(utilidad_operativa),
margen_promedio = mean(margen_operativo),
transacciones = n(),
.groups = "drop"
) %>%
mutate(
participacion_ventas = ventas_totales / sum(ventas_totales),
participacion_utilidad = utilidad_total / sum(utilidad_total),
ventas_totales = dollar(ventas_totales, accuracy = 1),
utilidad_total = dollar(utilidad_total, accuracy = 1),
margen_promedio = percent(margen_promedio, accuracy = 0.1),
transacciones = comma(transacciones, accuracy = 1),
participacion_ventas = percent(participacion_ventas, accuracy = 0.1),
participacion_utilidad = percent(participacion_utilidad, accuracy = 0.1)
) %>%
arrange(desc(ventas_totales))
# Mostrar Tabla 5.3
kable(tabla_metodo,
col.names = c("Metodo de Venta", "Ventas Totales", "Utilidad Total", "Margen Promedio",
"Transacciones", "% Ventas", "% Utilidad"),
caption = "Tabla 5.3: Ventas y Utilidad por Metodo de Venta") %>%
kable_styling(font_size = 11, full_width = FALSE) %>%
row_spec(0, bold = TRUE, background = "#F0F0F0")
| Metodo de Venta | Ventas Totales | Utilidad Total | Margen Promedio | Transacciones | % Ventas | % Utilidad |
|---|---|---|---|---|---|---|
| Online | $44,965,657 | $19,552,538 | 46.4% | 4,887 | 37.4% | 41.4% |
| Outlet | $39,536,618 | $14,913,301 | 39.5% | 3,017 | 32.9% | 31.6% |
| In-store | $35,664,375 | $12,759,129 | 35.6% | 1,740 | 29.7% | 27.0% |
# ============================================================
# TABLA 5.4: Ventas y Utilidad por Region y Metodo de Venta
# ============================================================
tabla_region_metodo <- datos_adidas %>%
group_by(region, metodo_venta) %>%
summarise(
ventas_totales = sum(ventas_totales),
utilidad_total = sum(utilidad_operativa),
margen_promedio = mean(margen_operativo),
transacciones = n(),
.groups = "drop"
) %>%
group_by(region) %>%
mutate(
participacion_en_region = ventas_totales / sum(ventas_totales)
) %>%
ungroup() %>%
mutate(
region = factor(region, levels = orden_regiones),
ventas_totales = dollar(ventas_totales, accuracy = 1),
utilidad_total = dollar(utilidad_total, accuracy = 1),
margen_promedio = percent(margen_promedio, accuracy = 0.1),
transacciones = comma(transacciones, accuracy = 1),
participacion_en_region = percent(participacion_en_region, accuracy = 0.1)
) %>%
arrange(region, desc(ventas_totales))
# Mostrar Tabla 5.4
kable(tabla_region_metodo,
col.names = c("Region", "Metodo de Venta", "Ventas Totales", "Utilidad Total",
"Margen Promedio", "Transacciones", "% en Region"),
caption = "Tabla 5.4: Ventas y Utilidad por Region y Metodo de Venta") %>%
kable_styling(font_size = 11, full_width = FALSE) %>%
row_spec(0, bold = TRUE, background = "#F0F0F0")
| Region | Metodo de Venta | Ventas Totales | Utilidad Total | Margen Promedio | Transacciones | % en Region |
|---|---|---|---|---|---|---|
| West | Outlet | $13,946,781 | $4,580,344 | 36.7% | 898 | 38.3% |
| West | Online | $11,950,976 | $4,942,152 | 43.9% | 1,152 | 32.8% |
| West | In-store | $10,538,400 | $3,495,088 | 34.0% | 398 | 28.9% |
| Northeast | Outlet | $8,856,415 | $3,231,522 | 37.5% | 757 | 35.3% |
| Northeast | Online | $4,626,777 | $2,246,832 | 47.9% | 936 | 18.4% |
| Northeast | In-store | $11,595,075 | $4,254,420 | 35.6% | 683 | 46.2% |
| Southeast | In-store | $7,236,125 | $2,558,256 | 34.9% | 194 | 33.9% |
| Southeast | Outlet | $2,071,151 | $754,401 | 37.8% | 238 | 9.7% |
| Southeast | Online | $12,067,160 | $5,080,402 | 44.9% | 792 | 56.5% |
| South | Online | $9,201,010 | $4,149,888 | 48.8% | 844 | 44.7% |
| South | In-store | $339,375 | $134,800 | 40.2% | 20 | 1.6% |
| South | Outlet | $11,062,971 | $4,936,917 | 44.8% | 864 | 53.7% |
| Midwest | Online | $7,119,734 | $3,133,264 | 47.0% | 1,163 | 42.7% |
| Midwest | In-store | $5,955,400 | $2,316,565 | 37.1% | 445 | 35.7% |
| Midwest | Outlet | $3,599,300 | $1,410,116 | 38.8% | 260 | 21.6% |
# ============================================================
# GRAFICO 5.5: Mapa de Calor - Margen por Region y Metodo
# ============================================================
datos_calor <- datos_adidas %>%
group_by(region, metodo_venta) %>%
summarise(
margen_promedio = mean(margen_operativo),
ventas_totales = sum(ventas_totales),
.groups = "drop"
) %>%
group_by(region) %>%
mutate(
participacion_en_region = ventas_totales / sum(ventas_totales)
) %>%
ungroup() %>%
mutate(
region = factor(region, levels = orden_regiones),
margen_promedio = round(margen_promedio * 100, 1),
participacion_en_region = round(participacion_en_region * 100, 1),
etiqueta = paste0(margen_promedio, "%") # Solo muestra el margen
)
g5_5 <- ggplot(datos_calor, aes(x = region, y = metodo_venta,
fill = margen_promedio)) +
geom_tile() +
geom_text(aes(label = etiqueta), size = 4, fontface = "bold") +
scale_fill_gradient(low = "white", high = "darkgreen", name = "Margen %") +
labs(title = "Grafico 5.5: Mapa de Calor - Margen por Region y Metodo",
subtitle = "Los numeros muestran el margen %",
x = "Region", y = "Metodo de Venta") +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
# ============================================================
# GRAFICO 5.6: Boxplot - Distribucion del Margen por Region
# ============================================================
g5_6 <- ggplot(datos_adidas, aes(x = factor(region, levels = orden_regiones),
y = margen_operativo,
fill = factor(region, levels = orden_regiones))) +
geom_boxplot(alpha = 0.7) +
scale_y_continuous(labels = percent_format()) +
labs(title = "Grafico 5.6: Distribucion del Margen por Region",
subtitle = "Regiones ordenadas de mayor a menor ventas (izquierda a derecha)",
x = "Region", y = "Margen Operativo") +
theme_minimal() +
theme(legend.position = "none", axis.text.x = element_text(angle = 45, hjust = 1))
# --- MOSTRAR GRAFICOS (version estatica - siempre visible) ---
print(g5_5)
print(g5_6)
Se logra observar que Online es el canal definitivo para tener el mejor margen de ganancias ya que en todas las regiones es el canal con mayor margen operativo (ver figura 5.5), también se logra observar que South es la región líder ya que tiene mayor margen, consistencia y eficiencia en todos los canales. También resulta interesante que West, siendo la región con más ventas, tiene el margen más bajo, según los datos anteriores hablando exclusivamente en ventas West era la opción más llamativa pero observando los márgenes resulta que tienen áreas de mejora, también resulta interesante que regiones que no tenían tantas ventas totales destacan como lo es el caso de South. Se logra evidenciar que In-store es el menos rentable, lo que significa que presenta altos precios operativos para todas las regiones. Para finalizar, se destaca que el canal online es el canal predilecto en términos de margen operativo y que las regiones con menos volumen tienen muy buenos márgenes, lo que presenta un potencial de crecimiento.
El análisis del caso Adidas tenía 3 objetivos principales, primero entender el comportamiento de ventas, luego entender el comportamiento de la rentabilidad y finalmente poder proponer qué combinaciones estratégicas pueden beneficiar más a la empresa.
# Cargar librerías necesarias
library(scales)
library(dplyr)
library(ggplot2)
library(plotly)
library(kableExtra)
# --- SECCION: COMBINACIONES ESTRATEGICAS (PRODUCTO + REGION + METODO) ---
# --- PASO 1: TABLA RESUMEN POR COMBINACION ---
tabla_combinaciones <- datos_adidas %>%
group_by(producto, region, metodo_venta) %>%
summarise(
ventas_totales = sum(ventas_totales),
unidades_totales = sum(unidades_vendidas),
utilidad_total = sum(utilidad_operativa),
transacciones = n(),
margen_promedio = mean(margen_operativo),
.groups = "drop"
) %>%
mutate(
margen_ponderado = utilidad_total / ventas_totales,
ticket_promedio = ventas_totales / transacciones,
unidades_promedio = unidades_totales / transacciones
)
# ============================================================
# TABLA 6.1: TOP 3 COMBINACIONES POR VOLUMEN DE VENTAS
# ============================================================
top_3_volumen <- tabla_combinaciones %>%
arrange(desc(ventas_totales)) %>%
head(3) %>%
mutate(
ventas_totales = dollar(ventas_totales, accuracy = 1),
unidades_totales = comma(unidades_totales, accuracy = 1),
utilidad_total = dollar(utilidad_total, accuracy = 1),
transacciones = comma(transacciones, accuracy = 1),
margen_ponderado = percent(margen_ponderado, accuracy = 0.1),
ticket_promedio = dollar(ticket_promedio, accuracy = 0.01),
unidades_promedio = round(unidades_promedio, 1)
) %>%
select(producto, region, metodo_venta, ventas_totales, unidades_totales,
utilidad_total, margen_ponderado, ticket_promedio, unidades_promedio, transacciones)
# Mostrar Tabla 6.1
kable(top_3_volumen,
col.names = c("Producto", "Region", "Metodo", "Ventas Totales", "Unidades Totales",
"Utilidad Total", "Margen", "Ticket Prom", "Unid x Trans", "Transacciones"),
caption = "Tabla 6.1: TOP 3 COMBINACIONES POR VOLUMEN DE VENTAS") %>%
kable_styling(font_size = 11, full_width = FALSE) %>%
row_spec(0, bold = TRUE, background = "#F0F0F0") %>%
row_spec(1:3, background = "#FFFFCC")
| Producto | Region | Metodo | Ventas Totales | Unidades Totales | Utilidad Total | Margen | Ticket Prom | Unid x Trans | Transacciones |
|---|---|---|---|---|---|---|---|---|---|
| Men’s Street Footwear | Northeast | In-store | $3,376,000 | 65,500 | $1,337,275 | 39.6% | $29,356.52 | 569.6 | 115 |
| Men’s Street Footwear | West | Outlet | $2,827,944 | 58,820 | $1,025,207 | 36.3% | $18,728.11 | 389.5 | 151 |
| Men’s Street Footwear | Southeast | Online | $2,740,850 | 56,055 | $1,242,924 | 45.3% | $20,764.02 | 424.7 | 132 |
# ============================================================
# TABLA 6.2: TOP 3 COMBINACIONES POR RENTABILIDAD
# ============================================================
top_3_rentabilidad <- tabla_combinaciones %>%
filter(ventas_totales > 0) %>%
arrange(desc(margen_ponderado)) %>%
head(3) %>%
mutate(
ventas_totales = dollar(ventas_totales, accuracy = 1),
unidades_totales = comma(unidades_totales, accuracy = 1),
utilidad_total = dollar(utilidad_total, accuracy = 1),
transacciones = comma(transacciones, accuracy = 1),
margen_ponderado = percent(margen_ponderado, accuracy = 0.1),
ticket_promedio = dollar(ticket_promedio, accuracy = 0.01),
unidades_promedio = round(unidades_promedio, 1)
) %>%
select(producto, region, metodo_venta, ventas_totales, unidades_totales,
utilidad_total, margen_ponderado, ticket_promedio, unidades_promedio, transacciones)
# Mostrar Tabla 6.2
kable(top_3_rentabilidad,
col.names = c("Producto", "Region", "Metodo", "Ventas Totales", "Unidades Totales",
"Utilidad Total", "Margen", "Ticket Prom", "Unid x Trans", "Transacciones"),
caption = "Tabla 6.2: TOP 3 COMBINACIONES POR RENTABILIDAD (mayor margen)") %>%
kable_styling(font_size = 11, full_width = FALSE) %>%
row_spec(0, bold = TRUE, background = "#F0F0F0") %>%
row_spec(1:3, background = "#CCFFCC")
| Producto | Region | Metodo | Ventas Totales | Unidades Totales | Utilidad Total | Margen | Ticket Prom | Unid x Trans | Transacciones |
|---|---|---|---|---|---|---|---|---|---|
| Women’s Apparel | South | Outlet | $2,285,570 | 51,271 | $1,254,117 | 54.9% | $15,872.01 | 356.0 | 144 |
| Men’s Street Footwear | Northeast | Online | $1,258,314 | 25,169 | $677,000 | 53.8% | $8,066.12 | 161.3 | 156 |
| Women’s Athletic Footwear | South | Outlet | $1,456,124 | 36,640 | $725,032 | 49.8% | $10,111.97 | 254.4 | 144 |
# ============================================================
# TABLA 6.3: TOP 3 COMBINACIONES ESTRATEGICAS
# ============================================================
top_3_estrategicas <- tabla_combinaciones %>%
mutate(
volumen_score = ventas_totales / max(ventas_totales),
rentabilidad_score = margen_ponderado / max(margen_ponderado),
score_estrategico = (volumen_score * 0.5) + (rentabilidad_score * 0.5)
) %>%
arrange(desc(score_estrategico)) %>%
head(3) %>%
mutate(
ventas_totales = dollar(ventas_totales, accuracy = 1),
unidades_totales = comma(unidades_totales, accuracy = 1),
utilidad_total = dollar(utilidad_total, accuracy = 1),
transacciones = comma(transacciones, accuracy = 1),
margen_ponderado = percent(margen_ponderado, accuracy = 0.1),
ticket_promedio = dollar(ticket_promedio, accuracy = 0.01),
unidades_promedio = round(unidades_promedio, 1)
) %>%
select(producto, region, metodo_venta, ventas_totales, unidades_totales,
utilidad_total, margen_ponderado, ticket_promedio, unidades_promedio, transacciones)
# Mostrar Tabla 6.3
kable(top_3_estrategicas,
col.names = c("Producto", "Region", "Metodo", "Ventas Totales", "Unidades Totales",
"Utilidad Total", "Margen", "Ticket Prom", "Unid x Trans", "Transacciones"),
caption = "Tabla 6.3: TOP 3 COMBINACIONES ESTRATEGICAS (volumen + rentabilidad)") %>%
kable_styling(font_size = 11, full_width = FALSE) %>%
row_spec(0, bold = TRUE, background = "#F0F0F0") %>%
row_spec(1:3, background = "#CCCCFF")
| Producto | Region | Metodo | Ventas Totales | Unidades Totales | Utilidad Total | Margen | Ticket Prom | Unid x Trans | Transacciones |
|---|---|---|---|---|---|---|---|---|---|
| Men’s Street Footwear | Northeast | In-store | $3,376,000 | 65,500 | $1,337,275 | 39.6% | $29,356.52 | 569.6 | 115 |
| Women’s Apparel | South | Outlet | $2,285,570 | 51,271 | $1,254,117 | 54.9% | $15,872.01 | 356.0 | 144 |
| Men’s Street Footwear | Southeast | Online | $2,740,850 | 56,055 | $1,242,924 | 45.3% | $20,764.02 | 424.7 | 132 |
# ============================================================
# GRAFICO 6.4: Comparacion de las Top 3 Combinaciones por Categoria
# ============================================================
top_3_combinado <- bind_rows(
top_3_volumen %>% mutate(categoria = "Volumen"),
top_3_rentabilidad %>% mutate(categoria = "Rentabilidad"),
top_3_estrategicas %>% mutate(categoria = "Estrategica")
) %>%
mutate(
ventas_num = as.numeric(gsub("[\\$,]", "", ventas_totales)),
margen_num = as.numeric(gsub("%", "", margen_ponderado)),
etiqueta_completa = paste0(producto, " | ", region, " | ", metodo_venta)
)
g6_4 <- ggplot(top_3_combinado, aes(x = reorder(etiqueta_completa, ventas_num),
y = ventas_num / 1000000,
fill = categoria)) +
geom_col() +
geom_text(aes(label = dollar(ventas_num, accuracy = 1)), hjust = -0.1, size = 3) +
coord_flip() +
scale_y_continuous(labels = dollar_format(suffix = "M"), expand = expansion(mult = c(0, 0.2))) +
scale_fill_manual(values = c("Volumen" = "#FFFFCC", "Rentabilidad" = "#CCFFCC", "Estrategica" = "#CCCCFF")) +
labs(title = "Grafico 6.4: Comparacion de las Top 3 Combinaciones por Categoria",
subtitle = "Volumen (amarillo), Rentabilidad (verde) y Estrategicas (morado)",
x = "", y = "Ventas Totales (en millones)", fill = "Categoria") +
theme_minimal() +
theme(legend.position = "bottom")
# Convertir a plotly interactivo
g6_4_int <- ggplotly(g6_4, tooltip = "text") %>%
layout(hoverlabel = list(bgcolor = "white", font = list(size = 11)))
# Mostrar grafico
print(g6_4_int)
Los hallazgos del desempeño de ventas respaldan de manera clara el top 3 por volumen propuesto. Men’s Street Footwear, que representa el 23% de las ventas totales ($27.7M) y lidera en todas las regiones, es el producto protagonista de las tres combinaciones. En Northeast, segunda región nacional ($25.1M, 20.9%), esta línea genera $6.8M regional y un ticket promedio alto, lo que justifica el liderazgo de la combinación In-store en esa zona. En West, la región más grande del país (30.3%, $36.4M), Men’s Street Footwear es el producto #1 con $7.4M, y el canal Outlet es uno de los principales canales de distribucion de west, confirmando esta como una combinación de alto volumen. Finalmente, Southeast con Online aprovecha el patrón clave identificado: Online supera el 40% en los top distribuidores digitales, y Men’s Street Footwear mantiene su liderazgo también en esta región, logrando el mayor margen de las tres combinaciones (45.3%), demostrando que el canal digital potencia tanto volumen como rentabilidad.
Los hallazgos de rentabilidad validan directamente el top 3 por margen. Women’s Apparel - South - Outlet (54.9%) es la materialización perfecta de los hallazgos: South lidera eficiencia (46.7% margen) y South + Women’s Apparel fue identificada como la mejor combinación por margen (52%), siendo Outlet el canal que lo eleva aún más. Men’s Street Footwear - Northeast - Online (53.8%) confirma el hallazgo clave de que Online es el canal con mayor margen en todas las regiones, y que al combinar el producto líder ($11.6M utilidad) con el canal digital, el margen sube a 53.8%. Women’s Athletic Footwear - South - Outlet (49.8%) demuestra que South es tan eficiente que eleva incluso al producto que no es necesariamente lider en ventas o margenes.
El top 3 estratégico equilibra volumen y rentabilidad apoyándose en los hallazgos de ambas secciones. Men’s Street Footwear - Northeast - In-store combina el producto líder en ventas y utilidad con la segunda región nacional, donde esta combinación ya fue identificada como estrella . Aunque In-store es el canal menos rentable, el volumen excepcional (569 unidades/transacción) lo compensa generando el mayor monto absoluto del ranking. Women’s Apparel - South - Outlet materializa la región más eficiente (46.7% margen) con el segundo producto más rentable , logrando que genere una utilidad alta. Men’s Street Footwear - Southeast - Online confirma el hallazgo clave de que Online maximiza margen en todas las regiones, y que Southeast, siendo una región con un potencial de crecimiento latente con buena rentabilidad.
El análisis de ventas de Adidas muestra que Men’s Street Footwear y Women’s Apparel son los productos estrella en ventas y utilidad, mientras que West lidera en volumen (30.3%, $36.4M) pero presenta el margen más bajo (39.7%), evidenciando que mayor volumen no garantiza mayor rentabilidad. South, en cambio, demuestra ser la región más eficiente (46.7% margen), y Online es el canal predilecto en términos de margen operativo, superando el 40% en todos los distribuidores digitales, mientras In-store, pese a su alto volumen, resulta ser el menos rentable por sus costos operativos.
Integrando volumen, rentabilidad y canal, las combinaciones más estratégicas para Adidas apuntan a concentrar esfuerzos en Men’s Street Footwear en Northeast/West vía Online/Outlet para equilibrar escala y margen, y en Women’s Apparel en South vía Outlet para maximizar eficiencia operativa. Estas combinaciones no solo reúnen a las regiones y productos líderes en ambas dimensiones, sino que confirman que la clave del crecimiento sostenible está en priorizar el canal digital y las regiones con mayor eficiencia, más que en perseguir volumen a cualquier costo.