# Si es la primera vez, descomenta y ejecuta esta línea:
# install.packages(c("readxl","dplyr","tidyr","ggplot2","scales","knitr"))
library(readxl)
library(dplyr)
library(tidyr)
library(ggplot2)
library(scales)
library(knitr)
# Paleta corporativa (negro/gris Adidas + acento)
col_principal <- "#111111"
col_acento <- "#0A7D7D"
col_alerta <- "#C0362C"
col_suave <- "#9AA0A6"
tema_adidas <- theme_minimal(base_size = 13) +
theme(
plot.title = element_text(face = "bold", size = 15),
plot.subtitle = element_text(color = "gray35", size = 11),
legend.position = "bottom",
panel.grid.minor = element_blank()
)
theme_set(tema_adidas)En este informe asumimos el rol de analistas de datos de Adidas. El objetivo es evaluar el desempeño comercial y financiero de las distintas líneas de producto, canales de venta, regiones y distribuidores, a partir de una base de 9.648 registros de ventas en Estados Unidos.
El análisis es descriptivo, exploratorio y diagnóstico: no busca predecir, sino entender qué está pasando y por qué, para cerrar con recomendaciones accionables (analítica prescriptiva) dirigidas al equipo directivo.
Preguntas que guían el trabajo:
# AJUSTA ESTA RUTA a la ubicación del archivo en tu computador.
# Ejemplo Windows: "C:/Users/TuUsuario/Downloads/DatosCaso1.xlsx"
ruta <- "DatosCaso1.xlsx"
datos <- read_excel("C:/Users/Juanf/Downloads/DatosCaso1 (1).xlsx")
# Estructura general
glimpse(datos)## Rows: 9,648
## Columns: 11
## $ distribuidor <chr> "Foot Locker", "Foot Locker", "Foot Locker", "Foot …
## $ region <chr> "Northeast", "Northeast", "Northeast", "Northeast",…
## $ estado <chr> "New York", "New York", "New York", "New York", "Ne…
## $ ciudad <chr> "New York", "New York", "New York", "New York", "Ne…
## $ producto <chr> "Men's Street Footwear", "Men's Athletic Footwear",…
## $ 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_total <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 <chr> "In-store", "In-store", "In-store", "In-store", "In…
# Etiquetas en español para la presentación ejecutiva
datos <- datos %>%
mutate(
canal = recode(metodo_venta,
"In-store" = "Tienda física",
"Online" = "Online",
"Outlet" = "Outlet"),
linea = recode(producto,
"Men's Street Footwear" = "Calzado Urbano Hombre",
"Men's Athletic Footwear" = "Calzado Deportivo Hombre",
"Women's Street Footwear" = "Calzado Urbano Mujer",
"Women's Athletic Footwear" = "Calzado Deportivo Mujer",
"Men's Apparel" = "Ropa Hombre",
"Women's Apparel" = "Ropa Mujer"),
zona = recode(region,
"Northeast" = "Noreste",
"Southeast" = "Sureste",
"Midwest" = "Medio Oeste",
"South" = "Sur",
"West" = "Oeste"),
categoria = ifelse(grepl("Apparel", producto), "Ropa", "Calzado"),
genero = ifelse(grepl("Women", producto), "Mujer", "Hombre")
)
# Dimensiones y niveles de cada variable categórica
tibble(
Variable = c("Distribuidores", "Regiones", "Estados", "Ciudades",
"Productos", "Canales de venta", "Registros"),
Niveles = c(n_distinct(datos$distribuidor), n_distinct(datos$region),
n_distinct(datos$estado), n_distinct(datos$ciudad),
n_distinct(datos$producto), n_distinct(datos$metodo_venta),
nrow(datos))
) %>% kable(caption = "Tabla 1. Alcance de la base de datos")| Variable | Niveles |
|---|---|
| Distribuidores | 6 |
| Regiones | 5 |
| Estados | 50 |
| Ciudades | 52 |
| Productos | 6 |
| Canales de venta | 3 |
| Registros | 9648 |
Antes de analizar, verificamos la consistencia de la base. Este paso es clave: si un directivo va a tomar decisiones con estos números, debe saber que están validados.
# 1) Valores faltantes
faltantes <- colSums(is.na(datos))
# 2) Registros duplicados exactos
n_duplicados <- sum(duplicated(datos[, 1:11]))
# 3) Coherencia contable: ventas_total = precio_unidad * unidades_vendidas
coherencia_ventas <- mean(
abs(datos$precio_unidad * datos$unidades_vendidas - datos$ventas_total) < 1e-6
)
# 4) Coherencia: margen_operativo = utilidad_operativa / ventas_total
margen_calc <- ifelse(datos$ventas_total > 0,
datos$utilidad_operativa / datos$ventas_total, NA)
coherencia_margen <- mean(abs(margen_calc - datos$margen_operativo) < 1e-6, na.rm = TRUE)
# 5) Registros sin operación (ventas en cero)
n_ceros <- sum(datos$ventas_total == 0)
tibble(
Verificación = c("Datos faltantes (total)",
"Registros duplicados exactos",
"Coherencia ventas = precio x unidades",
"Coherencia margen = utilidad / ventas",
"Registros con ventas en cero"),
Resultado = c(sum(faltantes),
n_duplicados,
percent(coherencia_ventas, accuracy = 0.1),
percent(coherencia_margen, accuracy = 0.1),
n_ceros)
) %>% kable(caption = "Tabla 2. Diagnóstico de calidad de datos")| Verificación | Resultado |
|---|---|
| Datos faltantes (total) | 0 |
| Registros duplicados exactos | 262 |
| Coherencia ventas = precio x unidades | 100.0% |
| Coherencia margen = utilidad / ventas | 100.0% |
| Registros con ventas en cero | 4 |
Hallazgo de calidad. La base no tiene datos faltantes y es contablemente coherente: las ventas totales corresponden exactamente al precio por unidad multiplicado por las unidades vendidas en el 100% de los casos. Esto significa que
ventas_totalymargen_operativoson variables derivadas, no independientes, lo cual condiciona cómo interpretamos las correlaciones más adelante.Se detectaron registros duplicados exactos y 4 registros con ventas en cero. Los duplicados pueden corresponder a transacciones legítimas repetidas (mismo producto, misma tienda, mismo precio en días distintos), por lo que se conservan para no subestimar el volumen. Los registros en cero se excluyen únicamente de los análisis de márgenes, donde una división por cero carece de sentido económico.
# Base para análisis de rentabilidad (excluye operaciones nulas)
datos_rent <- datos %>% filter(ventas_total > 0)resumen_num <- datos %>%
select(precio_unidad, unidades_vendidas, ventas_total,
utilidad_operativa, margen_operativo) %>%
pivot_longer(everything(), names_to = "Variable", values_to = "Valor") %>%
group_by(Variable) %>%
summarise(
Media = mean(Valor),
Mediana = median(Valor),
`Desv. Est.` = sd(Valor),
`CV (%)` = 100 * sd(Valor) / mean(Valor),
Mínimo = min(Valor),
`P25` = quantile(Valor, 0.25),
`P75` = quantile(Valor, 0.75),
Máximo = max(Valor),
.groups = "drop"
) %>%
mutate(across(where(is.numeric), ~ round(.x, 2)))
kable(resumen_num, caption = "Tabla 3. Estadísticas descriptivas de las variables numéricas")| Variable | Media | Mediana | Desv. Est. | CV (%) | Mínimo | P25 | P75 | Máximo |
|---|---|---|---|---|---|---|---|---|
| margen_operativo | 0.42 | 0.41 | 0.10 | 22.98 | 0.1 | 0.35 | 0.49 | 0.8 |
| precio_unidad | 45.22 | 45.00 | 14.71 | 32.52 | 7.0 | 35.00 | 55.00 | 110.0 |
| unidades_vendidas | 256.93 | 176.00 | 214.25 | 83.39 | 0.0 | 106.00 | 350.00 | 1275.0 |
| utilidad_operativa | 4894.79 | 3262.98 | 4866.46 | 99.42 | 0.0 | 1753.44 | 6192.36 | 39000.0 |
| ventas_total | 12455.08 | 7803.50 | 12716.39 | 102.10 | 0.0 | 4065.25 | 15864.50 | 82500.0 |
Cómo leer esta tabla. El coeficiente de variación (CV) es la medida clave aquí porque permite comparar la dispersión entre variables con unidades distintas.
unidades_vendidasyventas_totaltienen un CV superior al 80%: la operación es muy heterogénea. Hay transacciones de pocas unidades y transacciones masivas conviviendo en la misma base.- En ambas, la media supera ampliamente a la mediana (ventas: media ≈ USD 12.455 vs. mediana ≈ USD 7.804). Esto indica una distribución asimétrica a la derecha: unas pocas operaciones grandes arrastran el promedio hacia arriba. Para el comité directivo, la mediana es el indicador más representativo de la operación típica.
margen_operativoes la variable más estable (CV ≈ 23%): Adidas opera en una banda de rentabilidad relativamente controlada, entre 35% y 49% en la mitad central de los casos.
ggplot(datos, aes(x = ventas_total)) +
geom_histogram(bins = 50, fill = col_acento, color = "white", alpha = 0.9) +
geom_vline(aes(xintercept = median(ventas_total)),
color = col_alerta, linetype = "dashed", size = 1) +
geom_vline(aes(xintercept = mean(ventas_total)),
color = col_principal, linetype = "dotted", size = 1) +
annotate("text", x = median(datos$ventas_total), y = Inf,
label = "Mediana", vjust = 2, hjust = -0.15,
color = col_alerta, fontface = "bold", size = 4) +
annotate("text", x = mean(datos$ventas_total), y = Inf,
label = "Media", vjust = 4, hjust = -0.2,
color = col_principal, fontface = "bold", size = 4) +
scale_x_continuous(labels = dollar) +
scale_y_continuous(labels = comma) +
labs(
title = "La mayoría de transacciones son pequeñas; pocas son muy grandes",
subtitle = "Distribución del valor de venta por transacción (n = 9.648)",
x = "Ventas totales por transacción (USD)", y = "Número de transacciones"
)Interpretación. La distribución tiene una cola derecha pronunciada. La media (línea punteada) queda a la derecha de la mediana (línea discontinua), confirmando la asimetría. Decisión de negocio: los objetivos comerciales por tienda no deberían fijarse sobre el promedio, porque más de la mitad de las transacciones quedan por debajo de él; usar la mediana evita metas inalcanzables para el punto de venta típico.
prod <- datos %>%
group_by(linea) %>%
summarise(
ventas = sum(ventas_total),
unidades = sum(unidades_vendidas),
utilidad = sum(utilidad_operativa),
.groups = "drop"
) %>%
mutate(
participacion = ventas / sum(ventas),
margen_efectivo = utilidad / ventas
) %>%
arrange(desc(ventas))
kable(
prod %>% mutate(
ventas = dollar(ventas, accuracy = 1),
unidades = comma(unidades),
utilidad = dollar(utilidad, accuracy = 1),
participacion = percent(participacion, accuracy = 0.1),
margen_efectivo = percent(margen_efectivo, accuracy = 0.1)
),
col.names = c("Línea de producto", "Ventas", "Unidades", "Utilidad",
"% Participación", "Margen efectivo"),
caption = "Tabla 4. Desempeño por línea de producto"
)| Línea de producto | Ventas | Unidades | Utilidad | % Participación | Margen efectivo |
|---|---|---|---|---|---|
| Calzado Urbano Hombre | $27,680,769 | 593,320 | $11,629,046 | 23.0% | 42.0% |
| Ropa Mujer | $23,870,985 | 433,827 | $9,685,221 | 19.9% | 40.6% |
| Calzado Deportivo Hombre | $20,577,180 | 435,526 | $7,437,457 | 17.1% | 36.1% |
| Calzado Urbano Mujer | $17,201,563 | 392,269 | $6,494,017 | 14.3% | 37.8% |
| Ropa Hombre | $16,520,632 | 306,683 | $6,381,405 | 13.7% | 38.6% |
| Calzado Deportivo Mujer | $14,315,521 | 317,236 | $5,597,822 | 11.9% | 39.1% |
ggplot(prod, aes(x = reorder(linea, ventas), y = ventas)) +
geom_col(fill = col_principal, width = 0.7) +
geom_text(aes(label = percent(participacion, accuracy = 0.1)),
hjust = -0.15, size = 4, fontface = "bold", color = col_acento) +
coord_flip() +
scale_y_continuous(labels = dollar, expand = expansion(mult = c(0, 0.15))) +
labs(
title = "El Calzado Urbano de Hombre lidera las ventas de Adidas",
subtitle = "Ventas acumuladas y participación sobre el total",
x = NULL, y = "Ventas totales (USD)"
)Interpretación. El portafolio está razonablemente diversificado: ninguna línea supera el 25% de participación, lo que reduce el riesgo de depender de un solo producto. Sin embargo, Calzado Urbano Hombre aporta cerca de una cuarta parte de los ingresos y, como veremos, es también la línea más rentable — una combinación poco habitual y muy valiosa.
reg <- datos %>%
group_by(zona) %>%
summarise(ventas = sum(ventas_total),
utilidad = sum(utilidad_operativa),
unidades = sum(unidades_vendidas), .groups = "drop") %>%
mutate(participacion = ventas / sum(ventas),
margen_efectivo = utilidad / ventas) %>%
arrange(desc(ventas))
ggplot(reg, aes(x = reorder(zona, -ventas), y = ventas)) +
geom_col(fill = col_acento, width = 0.65) +
geom_text(aes(label = percent(participacion, accuracy = 0.1)),
vjust = -0.6, fontface = "bold", size = 4.2) +
scale_y_continuous(labels = dollar, expand = expansion(mult = c(0, 0.12))) +
labs(
title = "El Oeste concentra el 30% de las ventas totales",
subtitle = "Ventas acumuladas por región",
x = NULL, y = "Ventas totales (USD)"
)canal <- datos %>%
group_by(canal) %>%
summarise(
ventas = sum(ventas_total),
utilidad = sum(utilidad_operativa),
transacciones = n(),
# Ticket mediano: medida robusta frente a la asimetría de la distribución
ticket_mediano = median(ventas_total),
.groups = "drop"
) %>%
mutate(participacion = ventas / sum(ventas),
margen_efectivo = utilidad / ventas) %>%
select(canal, ventas, utilidad, transacciones,
participacion, margen_efectivo, ticket_mediano)
kable(
canal %>% arrange(desc(ventas)) %>%
mutate(ventas = dollar(ventas, accuracy = 1),
utilidad = dollar(utilidad, accuracy = 1),
transacciones = comma(transacciones),
participacion = percent(participacion, accuracy = 0.1),
margen_efectivo = percent(margen_efectivo, accuracy = 0.1),
ticket_mediano = dollar(ticket_mediano, accuracy = 1)),
col.names = c("Canal", "Ventas", "Utilidad", "N° transacciones",
"% Participación", "Margen efectivo", "Ticket mediano"),
caption = "Tabla 5. Desempeño por canal de venta"
)| Canal | Ventas | Utilidad | N° transacciones | % Participación | Margen efectivo | Ticket mediano |
|---|---|---|---|---|---|---|
| Online | $44,965,657 | $19,552,538 | 4,889 | 37.4% | 43.5% | $6,000 |
| Outlet | $39,536,618 | $14,913,301 | 3,019 | 32.9% | 37.7% | $7,785 |
| Tienda física | $35,664,375 | $12,759,129 | 1,740 | 29.7% | 35.8% | $16,875 |
ggplot(canal, aes(x = reorder(canal, -ventas), y = ventas, fill = canal)) +
geom_col(width = 0.6, show.legend = FALSE) +
geom_text(aes(label = paste0(percent(participacion, accuracy = 0.1),
"\nmargen ", percent(margen_efectivo, accuracy = 0.1))),
vjust = -0.3, fontface = "bold", size = 4, lineheight = 1.1) +
scale_fill_manual(values = c("Online" = col_acento,
"Outlet" = col_suave,
"Tienda física" = col_principal)) +
scale_y_continuous(labels = dollar, expand = expansion(mult = c(0, 0.20))) +
labs(
title = "Online vende más y además gana más por cada dólar vendido",
subtitle = "Ventas totales, participación y margen operativo efectivo por canal",
x = NULL, y = "Ventas totales (USD)"
)Hallazgo central del informe. El canal Online no solo es el de mayor facturación (≈ 37% del total), sino también el de mayor margen efectivo (≈ 43,5%), frente a Tienda física (≈ 35,8%). La diferencia de casi 8 puntos porcentuales es económicamente muy significativa: sobre los ingresos de tienda física, cada punto de margen representa cientos de miles de dólares.
Esto rompe el supuesto habitual de que el canal digital canibaliza rentabilidad por descuentos. En Adidas ocurre lo contrario, probablemente por menores costos de operación (sin arriendo comercial ni personal de piso) y menor necesidad de liquidación de inventario.
dist <- datos %>%
group_by(distribuidor) %>%
summarise(ventas = sum(ventas_total),
utilidad = sum(utilidad_operativa), .groups = "drop") %>%
mutate(participacion = ventas / sum(ventas),
margen_efectivo = utilidad / ventas) %>%
arrange(desc(ventas))
ggplot(dist, aes(x = reorder(distribuidor, ventas), y = ventas,
fill = margen_efectivo)) +
geom_col(width = 0.7) +
geom_text(aes(label = percent(margen_efectivo, accuracy = 0.1)),
hjust = -0.15, size = 3.8, fontface = "bold") +
coord_flip() +
scale_fill_gradient(low = col_suave, high = col_acento,
labels = percent, name = "Margen efectivo") +
scale_y_continuous(labels = dollar, expand = expansion(mult = c(0, 0.15))) +
labs(
title = "Sports Direct vende menos que West Gear, pero es el más rentable",
subtitle = "Ventas por distribuidor; el color y la etiqueta indican el margen efectivo",
x = NULL, y = "Ventas totales (USD)"
)top_ciudades <- datos %>%
group_by(ciudad, zona) %>%
summarise(ventas = sum(ventas_total), .groups = "drop") %>%
arrange(desc(ventas)) %>%
slice_head(n = 10)
ggplot(top_ciudades, aes(x = reorder(ciudad, ventas), y = ventas, fill = zona)) +
geom_col(width = 0.7) +
coord_flip() +
scale_y_continuous(labels = dollar, expand = expansion(mult = c(0, 0.08))) +
scale_fill_brewer(palette = "Dark2", name = "Región") +
labs(
title = "Top 10 ciudades por facturación",
subtitle = "La concentración geográfica es un riesgo y una oportunidad",
x = NULL, y = "Ventas totales (USD)"
)Interpretación. Las 10 ciudades principales concentran una porción muy relevante del negocio. Nueva York y San Francisco encabezan la lista. Para el comité esto tiene dos lecturas: (1) son los mercados donde conviene proteger la posición con inventario y servicio prioritario; (2) la dependencia de pocas plazas urbanas expone a Adidas a shocks locales (competencia, caída del tráfico peatonal, cierres).
ggplot(datos, aes(x = reorder(linea, ventas_total, FUN = median),
y = ventas_total)) +
geom_boxplot(fill = col_acento, alpha = 0.35, outlier.alpha = 0.25,
outlier.color = col_alerta, outlier.size = 1) +
coord_flip() +
scale_y_continuous(labels = dollar) +
labs(
title = "Alta variabilidad y presencia de valores atípicos en todas las líneas",
subtitle = "Distribución del valor de venta por transacción según línea de producto",
x = NULL, y = "Ventas por transacción (USD)"
)Interpretación. Todas las líneas presentan valores atípicos hacia arriba (puntos rojos): transacciones excepcionalmente grandes. No son errores de digitación —son coherentes contablemente— sino probablemente ventas mayoristas o campañas promocionales de alto volumen. Recomendamos no eliminarlos, sino analizarlos aparte: entender qué los origina es entender cómo se replican.
ggplot(datos_rent, aes(x = margen_operativo)) +
geom_histogram(bins = 40, fill = col_principal, color = "white", alpha = 0.9) +
geom_vline(xintercept = mean(datos_rent$margen_operativo),
color = col_alerta, linetype = "dashed", size = 1) +
scale_x_continuous(labels = percent) +
scale_y_continuous(labels = comma) +
labs(
title = "El margen operativo se concentra entre 35% y 50%",
subtitle = paste0("Margen promedio: ",
percent(mean(datos_rent$margen_operativo), accuracy = 0.1),
" | Desviación estándar: ",
percent(sd(datos_rent$margen_operativo), accuracy = 0.1)),
x = "Margen operativo", y = "Número de transacciones"
)ggplot(datos_rent, aes(x = canal, y = margen_operativo, fill = canal)) +
geom_boxplot(alpha = 0.75, width = 0.55, outlier.alpha = 0.2) +
stat_summary(fun = mean, geom = "point", shape = 18, size = 4,
color = col_alerta) +
scale_fill_manual(values = c("Online" = col_acento,
"Outlet" = col_suave,
"Tienda física" = "#5A6268")) +
scale_y_continuous(labels = percent) +
labs(
title = "El canal Online es sistemáticamente más rentable",
subtitle = "Distribución del margen operativo por canal (el rombo rojo marca la media)",
x = NULL, y = "Margen operativo"
) +
theme(legend.position = "none")Interpretación. No se trata solo de que el promedio sea mayor: toda la distribución del canal Online está desplazada hacia arriba. Su mediana supera incluso el percentil 75 de Tienda física. Es decir, una venta online típica es más rentable que el 75% de las ventas en tienda. Esta es una diferencia estructural, no un efecto de unos pocos casos extremos.
matriz <- datos %>%
group_by(zona) %>%
summarise(ventas = sum(ventas_total),
utilidad = sum(utilidad_operativa), .groups = "drop") %>%
mutate(margen_efectivo = utilidad / ventas)
ggplot(matriz, aes(x = ventas, y = margen_efectivo)) +
geom_hline(yintercept = sum(matriz$utilidad) / sum(matriz$ventas),
linetype = "dashed", color = col_suave) +
geom_vline(xintercept = mean(matriz$ventas),
linetype = "dashed", color = col_suave) +
geom_point(aes(size = ventas), color = col_acento, alpha = 0.8,
show.legend = FALSE) +
geom_text(aes(label = zona), vjust = -1.6, fontface = "bold", size = 4.3) +
scale_x_continuous(labels = dollar,
expand = expansion(mult = c(0.15, 0.20))) +
scale_y_continuous(labels = percent,
expand = expansion(mult = c(0.15, 0.20))) +
scale_size(range = c(5, 14)) +
labs(
title = "Volumen y rentabilidad no van de la mano entre regiones",
subtitle = "Las líneas punteadas marcan el promedio de ventas y el margen global",
x = "Ventas totales (USD)", y = "Margen operativo efectivo"
)Hallazgo clave para la dirección. Existe una tensión entre escala y rentabilidad:
- El Oeste es la región de mayor facturación, pero tiene el margen más bajo (≈ 35,7%). Vende mucho, pero gana poco por dólar vendido.
- El Sur factura menos, pero es la región más rentable (≈ 44,8%).
El Oeste es un mercado grande donde Adidas parece estar comprando participación con precio o promoción. Si se lograra llevar el margen del Oeste al nivel del Sur, el impacto en utilidad sería de varios millones de dólares sin vender una unidad adicional. Esa es, posiblemente, la mayor oportunidad identificada en este análisis.
oeste <- matriz %>% filter(zona == "Oeste")
sur <- matriz %>% filter(zona == "Sur")
oportunidad <- oeste$ventas * (sur$margen_efectivo - oeste$margen_efectivo)
cat("Utilidad adicional si el Oeste alcanzara el margen del Sur:",
dollar(oportunidad, accuracy = 1), "\n")## Utilidad adicional si el Oeste alcanzara el margen del Sur: $3,290,432
cat("Equivale a un incremento del",
percent(oportunidad / sum(matriz$utilidad), accuracy = 0.1),
"sobre la utilidad operativa total.\n")## Equivale a un incremento del 7.0% sobre la utilidad operativa total.
vars <- datos %>%
select(`Precio unitario` = precio_unidad,
`Unidades vendidas` = unidades_vendidas,
`Ventas totales` = ventas_total,
`Utilidad operativa` = utilidad_operativa,
`Margen operativo` = margen_operativo)
mat_cor <- round(cor(vars, method = "pearson"), 3)
kable(mat_cor, caption = "Tabla 6. Matriz de correlaciones de Pearson")| Precio unitario | Unidades vendidas | Ventas totales | Utilidad operativa | Margen operativo | |
|---|---|---|---|---|---|
| Precio unitario | 1.000 | 0.266 | 0.540 | 0.504 | -0.137 |
| Unidades vendidas | 0.266 | 1.000 | 0.919 | 0.872 | -0.305 |
| Ventas totales | 0.540 | 0.919 | 1.000 | 0.935 | -0.302 |
| Utilidad operativa | 0.504 | 0.872 | 0.935 | 1.000 | -0.047 |
| Margen operativo | -0.137 | -0.305 | -0.302 | -0.047 | 1.000 |
cor_largo <- as.data.frame(as.table(mat_cor))
names(cor_largo) <- c("Var1", "Var2", "Correlacion")
ggplot(cor_largo, aes(x = Var1, y = Var2, fill = Correlacion)) +
geom_tile(color = "white", size = 1) +
geom_text(aes(label = sprintf("%.2f", Correlacion)),
fontface = "bold", size = 4,
color = ifelse(abs(cor_largo$Correlacion) > 0.6, "white", "gray20")) +
scale_fill_gradient2(low = col_alerta, mid = "white", high = col_acento,
midpoint = 0, limits = c(-1, 1), name = "r de Pearson") +
labs(title = "Mapa de calor de correlaciones",
subtitle = "Relación lineal entre las variables financieras",
x = NULL, y = NULL) +
theme(axis.text.x = element_text(angle = 25, hjust = 1))Interpretación — y una advertencia metodológica importante.
ventas_totalcorrelaciona casi perfectamente conunidades_vendidas(r ≈ 0,92) y conutilidad_operativa(r ≈ 0,94). Esto no es un hallazgo de negocio: son relaciones contables por construcción (las ventas se calculan como precio × unidades). Reportarlas como “descubrimiento” sería un error de interpretación.- El resultado realmente informativo es la correlación entre
precio_unidadyunidades_vendidas: r ≈ +0,27, positiva. En una lógica de demanda clásica esperaríamos lo contrario.- El
margen_operativocorrelaciona negativamente con las unidades vendidas (r ≈ −0,31): las operaciones de mayor volumen tienden a tener menor margen, señal típica de descuentos por volumen.
ggplot(datos, aes(x = precio_unidad, y = unidades_vendidas)) +
geom_point(alpha = 0.12, color = col_principal, size = 1) +
geom_smooth(method = "lm", se = TRUE, color = col_alerta, size = 1.1) +
scale_x_continuous(labels = dollar) +
scale_y_continuous(labels = comma) +
labs(
title = "Precios más altos NO se traducen en menor volumen",
subtitle = paste0("Correlación de Pearson: r = ",
round(cor(datos$precio_unidad, datos$unidades_vendidas), 3),
" (relación positiva y débil)"),
x = "Precio por unidad (USD)", y = "Unidades vendidas"
)Interpretación. La pendiente es positiva, no negativa. Adidas no está compitiendo por precio: los productos de mayor precio unitario mantienen —e incluso superan— el volumen de los más económicos. Esto es evidencia del poder de marca.
Implicación directiva: existe espacio para revisar la política de descuentos. Si bajar el precio no es lo que está generando el volumen, los descuentos aplicados están erosionando margen sin comprar demanda adicional.
datos_rango <- datos_rent %>%
mutate(rango_precio = cut(
precio_unidad,
breaks = c(-Inf, 30, 45, 60, Inf),
labels = c("Bajo (< $30)", "Medio ($30–$45)",
"Alto ($45–$60)", "Premium (> $60)")
))
resumen_rango <- datos_rango %>%
group_by(rango_precio) %>%
summarise(
transacciones = n(),
unidades_medianas = median(unidades_vendidas),
margen_promedio = mean(margen_operativo),
ventas = sum(ventas_total),
.groups = "drop"
)
kable(
resumen_rango %>% mutate(
transacciones = comma(transacciones),
unidades_medianas = comma(unidades_medianas),
margen_promedio = percent(margen_promedio, accuracy = 0.1),
ventas = dollar(ventas, accuracy = 1)
),
col.names = c("Rango de precio", "N° transacciones", "Unidades (mediana)",
"Margen promedio", "Ventas totales"),
caption = "Tabla 7. Desempeño por rango de precio"
)| Rango de precio | N° transacciones | Unidades (mediana) | Margen promedio | Ventas totales |
|---|---|---|---|---|
| Bajo (< $30) | 1,443 | 140 | 44.0% | $6,458,929 |
| Medio ($30–$45) | 3,664 | 165 | 42.7% | $32,544,222 |
| Alto ($45–$60) | 3,177 | 195 | 42.4% | $46,030,724 |
| Premium (> $60) | 1,360 | 300 | 39.2% | $35,132,775 |
ggplot(datos_rango, aes(x = rango_precio, y = margen_operativo,
fill = rango_precio)) +
geom_boxplot(alpha = 0.8, width = 0.6, outlier.alpha = 0.15,
show.legend = FALSE) +
scale_fill_brewer(palette = "BuGn") +
scale_y_continuous(labels = percent) +
labs(
title = "El margen se mantiene estable en todos los rangos de precio",
subtitle = "Distribución del margen operativo según nivel de precio unitario",
x = NULL, y = "Margen operativo"
)combo <- datos %>%
group_by(linea, canal) %>%
summarise(ventas = sum(ventas_total),
utilidad = sum(utilidad_operativa), .groups = "drop") %>%
mutate(margen_efectivo = utilidad / ventas)
ggplot(combo, aes(x = canal, y = linea, fill = margen_efectivo)) +
geom_tile(color = "white", size = 1.2) +
geom_text(aes(label = percent(margen_efectivo, accuracy = 0.1)),
fontface = "bold", size = 4, color = "gray15") +
scale_fill_gradient(low = "#F2F7F7", high = col_acento,
labels = percent, name = "Margen efectivo") +
labs(
title = "¿Dónde gana más Adidas? Matriz producto × canal",
subtitle = "Margen operativo efectivo de cada combinación",
x = NULL, y = NULL
)combo %>%
arrange(desc(margen_efectivo)) %>%
slice_head(n = 6) %>%
mutate(ventas = dollar(ventas, accuracy = 1),
utilidad = dollar(utilidad, accuracy = 1),
margen_efectivo = percent(margen_efectivo, accuracy = 0.1)) %>%
kable(col.names = c("Línea de producto", "Canal", "Ventas",
"Utilidad", "Margen efectivo"),
caption = "Tabla 8. Las 6 combinaciones producto–canal más rentables")| Línea de producto | Canal | Ventas | Utilidad | Margen efectivo |
|---|---|---|---|---|
| Ropa Mujer | Online | $8,966,155 | $4,104,331 | 45.8% |
| Calzado Urbano Hombre | Online | $10,365,158 | $4,715,551 | 45.5% |
| Calzado Deportivo Mujer | Online | $5,371,092 | $2,326,915 | 43.3% |
| Calzado Urbano Mujer | Online | $6,303,273 | $2,634,900 | 41.8% |
| Ropa Hombre | Online | $6,334,120 | $2,626,915 | 41.5% |
| Calzado Deportivo Hombre | Online | $7,625,859 | $3,143,928 | 41.2% |
Interpretación. El mapa de calor permite identificar celdas ganadoras: las combinaciones donde coinciden alto margen y volumen relevante. Estas son las que deben recibir prioridad de inventario, pauta publicitaria y espacio comercial.
| # | Hallazgo | Evidencia | Implicación |
|---|---|---|---|
| 1 | El canal Online lidera en ventas Y en rentabilidad | 37,4% de las ventas y margen efectivo de 43,5% vs. 35,8% en tienda física | Reasignar inversión hacia el canal digital |
| 2 | Volumen y margen no coinciden geográficamente | El Oeste factura el 30% con margen de 35,7%; el Sur factura 17% con margen de 44,8% | Plan de recuperación de margen en el Oeste |
| 3 | Un precio más alto no reduce el volumen vendido | Correlación precio–unidades positiva (r = +0,27) | Revisar y reducir la política de descuentos |
| 4 | Las operaciones de mayor volumen tienen menor margen | Correlación margen–unidades negativa (r = −0,31) | Condicionar los descuentos por volumen a un piso de margen |
| 5 | El portafolio está diversificado, sin dependencia crítica | Ninguna línea supera el 25% de participación | Riesgo de portafolio bajo; permite apostar por líneas ganadoras |
| 6 | Alta variabilidad operativa entre transacciones | Coeficiente de variación de ventas superior al 100%; media > mediana | Fijar metas con la mediana, no con el promedio |
La rentabilidad de Adidas es sólida y estable (margen operativo promedio cercano al 42%, con baja dispersión relativa). El problema no es la rentabilidad global, sino su distribución desigual entre canales y regiones.
El canal digital es el activo más valioso del negocio. Combina el mayor volumen con el mayor margen, un resultado poco frecuente que debe protegerse y escalarse.
Existe una brecha de eficiencia en el Oeste. Es el mercado más grande y, al mismo tiempo, el menos rentable. Esa asimetría es la mayor oportunidad cuantificada del análisis.
La marca tiene poder de fijación de precios. La ausencia de una relación negativa entre precio y volumen indica que la demanda no es especialmente sensible al precio, lo que cuestiona la intensidad promocional actual.
| Prioridad | Recomendación | Justificación basada en datos | Indicador de seguimiento |
|---|---|---|---|
| Alta | Reasignar presupuesto comercial hacia el canal Online | Online ya representa el mayor volumen con el mayor margen; cada dólar trasladado desde tienda física a digital mejora el margen en ~8 p.p. | % de ventas por canal y margen efectivo mensual |
| Alta | Plan de recuperación de margen en la región Oeste | Llevar el margen del Oeste al nivel del Sur generaría millones en utilidad adicional sin vender una unidad más | Margen operativo del Oeste vs. margen nacional |
| Media | Rediseñar la política de descuentos por volumen | La correlación margen–volumen es negativa y la correlación precio–volumen es positiva: los descuentos erosionan margen sin generar demanda | Margen promedio de transacciones con descuento |
| Media | Priorizar las combinaciones producto–canal de mayor margen | El mapa de calor producto × canal identifica celdas con margen muy superior al promedio | Utilidad por combinación producto–canal |
| Media | Replicar el modelo operativo de Sports Direct | Con ventas intermedias, Sports Direct logra el mayor margen efectivo entre distribuidores (~43%) | Margen efectivo por distribuidor |
## Informe generado con R version 4.6.1 (2026-06-24 ucrt)