Este informe desarrolla un analisis descriptivo y financiero de la base de ventas de Adidas. El objetivo es identificar patrones de demanda, eficiencia por canal y la relacion entre precio, volumen, ventas y utilidad operativa. Se presentan estadisticas de tendencia central y dispersion, visualizaciones comparativas, KPIs y un cierre con recomendaciones.
Preguntas guia: - Que tan concentradas estan las ventas y utilidades entre productos y canales?. - Como se relacionan el precio por unidad y las unidades vendidas (elasticidad)?. - Que canales convierten mejor ventas en utilidad (margen y utilidad por unidad)?. - Donde existen colas de bajo margen que deban corregirse?.
datos <- read_excel("Adidas.xlsx", sheet = "Data Sales Adidas") %>%
clean_names()
names(datos)
## [1] "retailer" "region" "state" "city"
## [5] "product" "price_per_unit" "units_sold" "total_sales"
## [9] "operating_profit" "operating_margin" "sales_method"
head(datos)
| retailer | region | state | city | product | price_per_unit | units_sold | total_sales | operating_profit | operating_margin | sales_method |
|---|---|---|---|---|---|---|---|---|---|---|
| Foot Locker | Northeast | New York | New York | Men’s Street Footwear | 50 | 1200 | 60000 | 300000 | 0.50 | In-store |
| Foot Locker | Northeast | New York | New York | Men’s Athletic Footwear | 50 | 1000 | 50000 | 150000 | 0.30 | In-store |
| Foot Locker | Northeast | New York | New York | Women’s Street Footwear | 40 | 1000 | 40000 | 140000 | 0.35 | In-store |
| Foot Locker | Northeast | New York | New York | Women’s Athletic Footwear | 45 | 850 | 38250 | 133875 | 0.35 | In-store |
| Foot Locker | Northeast | New York | New York | Men’s Apparel | 60 | 900 | 54000 | 162000 | 0.30 | In-store |
| Foot Locker | Northeast | New York | New York | Women’s Apparel | 50 | 1000 | 50000 | 125000 | 0.25 | In-store |
datos <- datos %>%
mutate(
utilidad_por_unidad = ifelse(total_sales > 0, operating_profit / units_sold, 0),
rentabilidad_sobre_ventas = ifelse(total_sales > 0, operating_profit / total_sales, 0)
)
head(datos)
| retailer | region | state | city | product | price_per_unit | units_sold | total_sales | operating_profit | operating_margin | sales_method | utilidad_por_unidad | rentabilidad_sobre_ventas |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Foot Locker | Northeast | New York | New York | Men’s Street Footwear | 50 | 1200 | 60000 | 300000 | 0.50 | In-store | 250.0 | 5.0 |
| Foot Locker | Northeast | New York | New York | Men’s Athletic Footwear | 50 | 1000 | 50000 | 150000 | 0.30 | In-store | 150.0 | 3.0 |
| Foot Locker | Northeast | New York | New York | Women’s Street Footwear | 40 | 1000 | 40000 | 140000 | 0.35 | In-store | 140.0 | 3.5 |
| Foot Locker | Northeast | New York | New York | Women’s Athletic Footwear | 45 | 850 | 38250 | 133875 | 0.35 | In-store | 157.5 | 3.5 |
| Foot Locker | Northeast | New York | New York | Men’s Apparel | 60 | 900 | 54000 | 162000 | 0.30 | In-store | 180.0 | 3.0 |
| Foot Locker | Northeast | New York | New York | Women’s Apparel | 50 | 1000 | 50000 | 125000 | 0.25 | In-store | 125.0 | 2.5 |
describe(select(datos, price_per_unit, units_sold, total_sales, operating_profit, operating_margin))
| vars | n | mean | sd | median | trimmed | mad | min | max | range | skew | kurtosis | se | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| price_per_unit | 1 | 9648 | 4.521663e+01 | 1.470540e+01 | 45.00 | 4.482655e+01 | 14.826000 | 7.0 | 110.0 | 103.0 | 0.3623328 | 0.4286307 | 0.1497125 |
| units_sold | 2 | 9648 | 2.569300e+02 | 2.142520e+02 | 176.00 | 2.214874e+02 | 134.916600 | 0.0 | 1275.0 | 1275.0 | 1.4618026 | 1.6972223 | 2.1812543 |
| total_sales | 3 | 9648 | 1.245508e+04 | 1.271639e+04 | 7803.50 | 9.958751e+03 | 6802.910100 | 0.0 | 82500.0 | 82500.0 | 1.9614341 | 4.1211673 | 129.4628799 |
| operating_profit | 4 | 9648 | 3.442524e+04 | 5.419311e+04 | 4371.42 | 2.227022e+04 | 5086.022235 | 0.0 | 390000.0 | 390000.0 | 2.2329038 | 5.8149019 | 551.7285492 |
| operating_margin | 5 | 9648 | 4.229913e-01 | 9.719740e-02 | 0.41 | 4.207021e-01 | 0.088956 | 0.1 | 0.8 | 0.7 | 0.2274108 | 0.1739254 | 0.0009895 |
datos %>%
summarise(
media_precio = mean(price_per_unit, na.rm = TRUE),
mediana_precio = median(price_per_unit, na.rm = TRUE),
sd_precio = sd(price_per_unit, na.rm = TRUE),
rango_precio = max(price_per_unit, na.rm = TRUE) - min(price_per_unit, na.rm = TRUE)
)
| media_precio | mediana_precio | sd_precio | rango_precio |
|---|---|---|---|
| 45.21663 | 45 | 14.7054 | 103 |
Analisis experto:
- La mediana es robusta ante outliers; comparar media
vs mediana revela sesgo (si media mucho mayor, hay cola derecha).
- El coeficiente de variacion (CV) permite comparar
dispersion entre variables en escalas distintas: CV alto en precio
indica estrategia de pricing heterogenea; CV alto en ventas sugiere
portafolio con ganadores y colas largas.
- Desviaciones muy altas justifican analizar concentracion (ver KPIs
Pareto). —
ventas_altas <- datos %>% filter(total_sales > mean(total_sales, na.rm = TRUE))
head(ventas_altas)
| retailer | region | state | city | product | price_per_unit | units_sold | total_sales | operating_profit | operating_margin | sales_method | utilidad_por_unidad | rentabilidad_sobre_ventas |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Foot Locker | Northeast | New York | New York | Men’s Street Footwear | 50 | 1200 | 60000 | 300000 | 0.50 | In-store | 250.0 | 5.0 |
| Foot Locker | Northeast | New York | New York | Men’s Athletic Footwear | 50 | 1000 | 50000 | 150000 | 0.30 | In-store | 150.0 | 3.0 |
| Foot Locker | Northeast | New York | New York | Women’s Street Footwear | 40 | 1000 | 40000 | 140000 | 0.35 | In-store | 140.0 | 3.5 |
| Foot Locker | Northeast | New York | New York | Women’s Athletic Footwear | 45 | 850 | 38250 | 133875 | 0.35 | In-store | 157.5 | 3.5 |
| Foot Locker | Northeast | New York | New York | Men’s Apparel | 60 | 900 | 54000 | 162000 | 0.30 | In-store | 180.0 | 3.0 |
| Foot Locker | Northeast | New York | New York | Women’s Apparel | 50 | 1000 | 50000 | 125000 | 0.25 | In-store | 125.0 | 2.5 |
Analisis experto:
- En términos financieros: esos indicadores sirven para diagnosticar si
la concentración en pocos productos de alto margen está sosteniendo la
rentabilidad global, Un porcentaje bajo de observaciones sobre el
promedio confirma concentracion; conviene priorizar su surtido, stock y
promesas de entrega.
online <- datos %>% filter(sales_method == "Online")
head(online)
| retailer | region | state | city | product | price_per_unit | units_sold | total_sales | operating_profit | operating_margin | sales_method | utilidad_por_unidad | rentabilidad_sobre_ventas |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| West Gear | South | Louisiana | New Orleans | Women’s Apparel | 65 | 575 | 37375 | 130812.5 | 0.35 | Online | 227.5 | 3.5 |
| West Gear | South | Louisiana | New Orleans | Men’s Street Footwear | 60 | 825 | 49500 | 198000.0 | 0.40 | Online | 240.0 | 4.0 |
| West Gear | South | Louisiana | New Orleans | Men’s Athletic Footwear | 70 | 700 | 49000 | 196000.0 | 0.40 | Online | 280.0 | 4.0 |
| West Gear | South | Louisiana | New Orleans | Women’s Street Footwear | 85 | 700 | 59500 | 238000.0 | 0.40 | Online | 340.0 | 4.0 |
| West Gear | South | Louisiana | New Orleans | Women’s Athletic Footwear | 85 | 575 | 48875 | 195500.0 | 0.40 | Online | 340.0 | 4.0 |
| West Gear | South | Louisiana | New Orleans | Men’s Apparel | 95 | 450 | 42750 | 192375.0 | 0.45 | Online | 427.5 | 4.5 |
Márgenes operativos (0.35 – 0.45) → son relativamente más altos que algunos valores observados en ventas físicas, pero al mismo tiempo muestran más dispersión. Eso significa que unas campañas online pueden ser muy rentables, mientras que otras no tanto.
Utilidad por unidad (227 – 427) → tiende a ser más elevada en comparación con algunos productos vendidos en tienda física. Eso sugiere que las campañas digitales permiten ajustar precios y captar clientes más dispuestos a pagar.
Rentabilidad sobre ventas (3.5 – 4.5) → bastante consistente, pero con variación suficiente como para indicar que las estrategias de precio y segmentación online generan resultados dispares.
ggplot(datos, aes(x = operating_margin)) +
geom_histogram(fill = colores_pastel[1], color = "white", bins = 15) +
theme_minimal() +
labs(title = "Distribucion del Margen Operativo", x = "Margen Operativo", y = "Frecuencia")
Lectura experta:
El histograma se concentra entre 0.3 y 0.5, con un pico cercano a 0.4.
Hay una cola hacia la izquierda (0.1 – 0.2) evidencia productos o
canales con márgenes mucho menores. La cola hacia la derecha es corta,
indica que muy pocos productos alcanzan márgenes extraordinarios
(>0.6). El grueso (entre 0.3 y 0.5) indica que la empresa mantiene un
margen operativo “saludable”, pero todavía vulnerable si los costos de
producción aumentan o si la competencia presiona los precios. Los
valores más altos (>0.6) probablemente corresponden a productos
premium o campañas online exitosas que logran cobrar más con bajo costo
relativo.
ggplot(datos, aes(x = sales_method, y = total_sales, fill = sales_method)) +
geom_boxplot(alpha = 0.7) +
scale_fill_manual(values = colores_pastel) +
theme_minimal() +
labs(title = "Boxplot de Ventas Totales por Metodo de Venta", x = "Metodo de Venta", y = "Ventas Totales")
lectura experta
In-store
Presenta la Mediana más alta, Caja más amplia, ventas más consistentes y estables que en otros canales. Muchos outliers hacia arriba significa que algunos productos o campañas en tienda generan ventas extraordinarias, que elevan la dispersión.
Online
Mediana claramente más baja.
Caja más comprimida, ventas generalmente bajas o moderadas. Sin embargo, hay múltiples outliers extremos hacia arriba (algunos cercanos a 80.000) indica que pocas campañas digitales logran escalar fuertemente, pero en promedio el canal es más débil que físico.
Outlet
Mediana algo superior a Online.
Caja amplia, aunque con mayor dispersión que In-store.
También presenta muchos outliers altos, lo que sugiere que ocasionalmente los outlets concentran grandes ventas (probablemente por liquidaciones o temporadas).
Interpretación El canal In-store domina en ventas totales regulares, lo cual refleja que aún es el principal motor de ingresos de Adidas en esta muestra.
El canal Online es más volátil: en promedio vende menos, pero algunos outliers muestran que tiene potencial explosivo en campañas puntuales (ejemplo: lanzamientos exclusivos o descuentos masivos).
Los Outlets actúan como un canal de soporte: generan volúmenes intermedios pero con una dispersión amplia. Son útiles para rotar inventario y liberar stock, aunque con riesgo de presionar márgenes.
ranking_unidades <- datos %>%
group_by(product) %>%
summarise(total_sales = sum(total_sales, na.rm = TRUE)) %>%
arrange(desc(total_sales)) %>%
head(10)
ggplot(ranking_unidades, aes(x = reorder(product, total_sales), y = total_sales, fill = product)) +
geom_bar(stat = "identity", alpha = 0.8) +
scale_fill_manual(values = rep(colores_pastel, length.out = 10)) +
coord_flip() +
theme_minimal() +
labs(title = "Top 6 productos por Ventas Totales", x = "Producto", y = "Ventas Totales")
lectura del grafico Podemos ver que el mercado
masculino domina fuertemente las ventas en Adidas, con “men’s street
footwear”, “athletic footwaer” y ” men’s apparel” conformando el 1-3-5
de los puestos en el top respectivamente.
ggplot(datos, aes(x = price_per_unit, y = units_sold)) +
geom_point(color = colores_pastel[2], alpha = 0.7, size = 3) +
geom_smooth(method = "lm", color = colores_pastel[3], se = FALSE) +
theme_minimal() +
labs(title = "Precio vs Unidades Vendidas", x = "Precio por Unidad", y = "Unidades Vendidas")
lectura Alta variabilidad: por cada nivel de precio,
hay un rango enorme de unidades vendidas (desde casi 0 hasta más de
1.000).
Se ven clústeres verticales → probablemente por precios estandarizados de catálogo (ej. $20, $30, $50, $60, etc.). Esto puede sugerir que Adidas está vendiendo productos premium (más caros) que, pese al precio elevado, tienen fuerte aceptación por marca, moda o exclusividad.
Los precios bajos no garantizan alto volumen: hay muchos casos de precios bajos con ventas muy reducidas. ## 6.5 Ventas Totales vs Utilidad Operativa
ggplot(datos, aes(x = total_sales, y = operating_profit, color = sales_method)) +
geom_point(size = 3, alpha = 0.8) +
scale_color_manual(values = colores_pastel) +
theme_minimal() +
labs(title = "Ventas Totales vs Utilidad Operativa", x = "Ventas Totales", y = "Utilidad Operativa")
lectura Existe una correlación positiva clara: a mayor
nivel de ventas, mayor utilidad operativa.
ranking_unidades <- datos %>%
group_by(product) %>%
summarise(total_sales = sum(units_sold, na.rm = TRUE)) %>%
arrange(desc(total_sales))
kable(head(ranking_unidades, 10), caption = "Top 6 productos más vendidos")
| product | total_sales |
|---|---|
| Men’s Street Footwear | 593320 |
| Men’s Athletic Footwear | 435526 |
| Women’s Apparel | 433827 |
| Women’s Street Footwear | 392269 |
| Women’s Athletic Footwear | 317236 |
| Men’s Apparel | 306683 |
ranking_metodo <- datos %>%
group_by(sales_method) %>%
summarise(rentabilidad_prom = mean(rentabilidad_sobre_ventas, na.rm = TRUE)) %>%
arrange(desc(rentabilidad_prom))
kable(ranking_metodo, caption = "Ranking de rentabilidad por método de venta")
| sales_method | rentabilidad_prom |
|---|---|
| In-store | 3.561207 |
| Outlet | 1.644147 |
| Online | 1.148366 |
Analisis experto:
- No todos los canales con mayor volumen son los mas rentables. La
decision de inversion debe guiarse por margen_prom y
utilidad_por_unidad, no solo por ventas.
- Canales con margen alto pero bajo volumen son candidatos a
escalamiento selectivo; canales con volumen alto y margen bajo requieren
renegociacion de costos o reglas de descuento. —
kpi_concentracion <- datos %>%
group_by(product) %>%
summarise(sales = sum(total_sales, na.rm = TRUE),
profit = sum(operating_profit, na.rm = TRUE),
units = sum(units_sold, na.rm = TRUE), .groups="drop") %>%
arrange(desc(sales)) %>%
mutate(cum_share_sales = cumsum(sales)/sum(sales)) %>%
mutate(rank = row_number())
share_top20 <- kpi_concentracion %>%
filter(rank <= ceiling(0.2*n())) %>%
summarise(share_sales_top20 = sum(sales)/sum(kpi_concentracion$sales),
share_profit_top20 = sum(profit)/sum(kpi_concentracion$profit))
canales <- datos %>%
group_by(sales_method) %>%
summarise(
sales = sum(total_sales, na.rm = TRUE),
profit = sum(operating_profit, na.rm = TRUE),
units = sum(units_sold, na.rm = TRUE),
margin = profit/sales,
profit_per_unit = profit/units
) %>% arrange(desc(margin))
canales
| sales_method | sales | profit | units | margin | profit_per_unit |
|---|---|---|---|---|---|
| In-store | 35664375 | 127591288 | 689990 | 3.577556 | 184.9176 |
| Outlet | 39536618 | 107988297 | 849778 | 2.731349 | 127.0782 |
| Online | 44965657 | 96555176 | 939093 | 2.147309 | 102.8175 |
modelo_elasticidad <- datos %>%
filter(price_per_unit > 0, units_sold > 0) %>%
mutate(lp = log(price_per_unit), lq = log(units_sold)) %>%
do(tidy(lm(lq ~ lp, data = .)))
coef_elast <- modelo_elasticidad %>% filter(term=="lp") %>% pull(estimate)
pval_elast <- modelo_elasticidad %>% filter(term=="lp") %>% pull(p.value)
kpis <- tibble::tibble(
Ventas_Totales = dollar(sum(datos$total_sales, na.rm = TRUE)),
Utilidad_Operativa = dollar(sum(datos$operating_profit, na.rm = TRUE)),
Margen_Operativo = percent(weighted.mean(datos$operating_margin, w = datos$total_sales, na.rm = TRUE)),
Top20_Share_Ventas = percent(share_top20$share_sales_top20),
Top20_Share_Utilidad = percent(share_top20$share_profit_top20),
Elasticidad_Precio_Cantidad = round(coef_elast, 2),
p_valor = signif(pval_elast, 3)
)
kable(kpis, caption = "KPIs y vínculos entre variables")
| Ventas_Totales | Utilidad_Operativa | Margen_Operativo | Top20_Share_Ventas | Top20_Share_Utilidad | Elasticidad_Precio_Cantidad | p_valor |
|---|---|---|---|---|---|---|
| $120,166,650 | $332,134,761 | 39% | 43% | 46% | 0.57 | 0 |
Analisis experto:
- Concentracion: si Top20_Share_Utilidad es mayor que
Top20_Share_Ventas, el mix estrella aporta margen desproporcionado;
proteger estos SKU y asegurar disponibilidad.
- Eficiencia por canal: priorizar los de mayor margen y
utilidad por unidad; canales con margen bajo deben revisarse costos
variables, comisiones y politicas de descuento.
- Elasticidad: coeficiente log-log negativo y
significativo (p_valor bajo) confirma sensibilidad a precio. Si su
magnitud es menor a 1 en valor absoluto, hay espacio para capturar
margen con mejoras de propuesta de valor; si es mayor a 1, las
promociones bien dirigidas aceleran volumen.
El análisis financiero evidencia que Adidas mantiene una posición sólida gracias a su capacidad de generar márgenes operativos positivos y al poder de marca que le permite sostener precios relativamente altos; sin embargo, se observa una alta concentración de ventas y utilidades en pocos productos, lo que expone a riesgos de dependencia. El canal online destaca por su mayor eficiencia en rentabilidad, mientras que el canal físico presenta altos volúmenes pero con costos que reducen márgenes, y los outlets funcionan como estrategia táctica de rotación sacrificando utilidad. Asimismo, la dispersión de márgenes indica la existencia de productos con baja o negativa rentabilidad, lo que sugiere la necesidad de revisar estrategias de precios, costos logísticos y surtido. En conjunto, los resultados sugieren priorizar el fortalecimiento del canal digital, optimizar costos de retail físico y diversificar el portafolio para asegurar sostenibilidad financiera de largo plazo.