# ── Carga de librerías ────────────────────────────────────────────────────────
library(readxl)
library(dplyr)
library(ggplot2)
library(plotly)
library(scales)
library(kableExtra)
library(tidyr)
library(forcats)
# ── Carga y preparación del dataset ──────────────────────────────────────────
datos_raw <- read_excel("DatosCaso1.xlsx")
# Calcular ventas_total a partir de precio × unidades (el Excel usa fórmulas)
datos_raw <- datos_raw %>%
mutate(ventas_total = precio_unidad * unidades_vendidas)
# Diccionario de traducciones (reutilizable en todo el documento)
datos <- datos_raw %>%
filter(!is.na(distribuidor)) %>% # eliminar filas vacías
mutate(
# Productos
producto_es = 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"
),
# Regiones
region_es = recode(region,
"West" = "Oeste",
"Northeast" = "Noreste",
"Southeast" = "Sureste",
"South" = "Sur",
"Midwest" = "Medio Oeste"
),
# Método de venta
metodo_es = recode(metodo_venta,
"In-store" = "Tienda Física",
"Online" = "En Línea",
"Outlet" = "Outlet"
),
# Margen como porcentaje
margen_pct = margen_operativo * 100
)
Adidas es una empresa multinacional líder en la industria de artículos deportivos, reconocida globalmente por su oferta de calzado, ropa y accesorios. El presente informe tiene como objetivo realizar un análisis descriptivo y exploratorio de su desempeño comercial en el mercado estadounidense, con el fin de comprender el comportamiento de sus ventas y rentabilidad en distintos segmentos.
Para ello, se aplican técnicas de analítica descriptiva que permiten examinar la distribución de las ventas, analizar la rentabilidad y explorar las relaciones entre variables clave que influyen en el desempeño comercial. A través de estadísticas descriptivas y visualizaciones interactivas, se busca identificar patrones relevantes y diferencias entre regiones, productos, distribuidores y canales de venta.
El dataset comprende 9648 registros de ventas distribuidos en 5 regiones, 6 categorías de producto y 6 distribuidores.
# ── Tabla resumen sin desviación estándar ────────────────────────────────
resumen_desc <- datos %>%
summarise(
across(
c(precio_unidad, unidades_vendidas, ventas_total,
utilidad_operativa, margen_pct),
list(
Media = ~round(mean(.x, na.rm = TRUE), 2),
Mediana = ~round(median(.x, na.rm = TRUE), 2),
Mínimo = ~round(min(.x, na.rm = TRUE), 2),
Máximo = ~round(max(.x, na.rm = TRUE), 2)
),
.names = "{.col}|{.fn}"
)
) %>%
pivot_longer(everything(),
names_to = c("Variable", "Estadístico"),
names_sep = "\\|") %>%
pivot_wider(names_from = "Estadístico", values_from = "value")
# Renombrar variables para presentación
resumen_desc$Variable <- recode(resumen_desc$Variable,
"precio_unidad" = "Precio por Unidad (USD)",
"unidades_vendidas" = "Unidades Vendidas",
"ventas_total" = "Ventas Totales (USD)",
"utilidad_operativa" = "Utilidad Operativa (USD)",
"margen_pct" = "Margen Operativo (%)"
)
resumen_desc %>%
kable(caption = "Tabla 1. Estadísticas Descriptivas de Variables Clave",
align = "lrrrr") %>% # ahora solo 4 columnas numéricas
kable_styling(bootstrap_options = c("striped", "hover", "condensed"),
full_width = FALSE) %>%
column_spec(1, bold = TRUE)
| Variable | Media | Mediana | Mínimo | Máximo |
|---|---|---|---|---|
| Precio por Unidad (USD) | 45.22 | 45.00 | 7 | 110 |
| Unidades Vendidas | 256.93 | 176.00 | 0 | 1275 |
| Ventas Totales (USD) | 12455.08 | 7803.50 | 0 | 82500 |
| Utilidad Operativa (USD) | 4894.79 | 3262.98 | 0 | 39000 |
| Margen Operativo (%) | 42.30 | 41.00 | 10 | 80 |
Interpretación: La tabla anterior muestra las principales medidas de tendencia central y variabilidad. El precio promedio por unidad es de $45.22, con una mediana de $45, lo que indica que la distribución de precios es relativamente simétrica. El margen operativo promedio del 42.3% refleja una rentabilidad sólida, con una desviación estándar que evidencia heterogeneidad entre productos y canales.
library(plotly)
library(dplyr)
library(scales)
# Traducir productos reales del Excel
datos <- datos %>%
mutate(producto_es = 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"
))
# Agrupar métricas
datos_resumen <- datos %>%
group_by(producto_es) %>%
summarise(
ventas = sum(ventas_total, na.rm = TRUE),
utilidad = sum(utilidad_operativa, na.rm = TRUE),
margen = mean(margen_operativo, na.rm = TRUE)
) %>%
arrange(utilidad)
# Convertir a factor ordenado
datos_resumen$producto_es <- factor(
datos_resumen$producto_es,
levels = datos_resumen$producto_es
)
# Gráfico profesional combinado
plot_ly(datos_resumen, x = ~producto_es) %>%
add_trace(
y = ~ventas,
name = "Ventas Totales",
type = "bar",
marker = list(color = "#2E7D32"),
yaxis = "y1",
hovertemplate =
"<b>%{x}</b><br>Ventas: $%{y:,.0f}<extra></extra>"
) %>%
add_trace(
y = ~utilidad,
name = "Utilidad Operativa",
type = "bar",
marker = list(color = "#1565C0"),
yaxis = "y1",
hovertemplate =
"<b>%{x}</b><br>Utilidad: $%{y:,.0f}<extra></extra>"
) %>%
add_trace(
y = ~margen,
name = "Margen Operativo",
type = "scatter",
mode = "lines+markers",
line = list(color = "black", width = 4),
marker = list(size = 8),
yaxis = "y2",
hovertemplate =
"<b>%{x}</b><br>Margen: %{y:.1%}<extra></extra>"
) %>%
layout(
title = list(
text = "<b> Figura 1. Comparación de Ventas Totales, Utilidad Operativa y Margen Operativo por Producto</b>",
x = 0.5
),
xaxis = list(
title = "<b>Producto</b>"
),
yaxis = list(
title = "<b>Ventas y Utilidad (USD)</b>",
tickprefix = "$",
separatethousands = TRUE
),
yaxis2 = list(
title = "<b>Margen Operativo (%)</b>",
overlaying = "y",
side = "right",
tickformat = ".0%"
),
barmode = "group",
plot_bgcolor = "white",
paper_bgcolor = "white"
)
Interpretación: El Calzado Deportivo Hombre lidera tanto en ventas como en utilidad operativa, seguido de Calzado Urbano Hombre. La línea de margen muestra que las categorías de Ropa tienen márgenes más elevados en proporción, lo que las convierte en segmentos estratégicamente atractivos a pesar de un volumen de ventas menor.
# ── Heatmap región × producto ─────────────────────────────────────────────────
tabla_heat <- datos %>%
group_by(region_es, producto_es) %>%
summarise(ventas_totales = sum(ventas_total, na.rm = TRUE), .groups = "drop")
# Ordenar ejes por total
orden_prod <- tabla_heat %>% group_by(producto_es) %>%
summarise(t = sum(ventas_totales)) %>% arrange(t) %>% pull(producto_es)
orden_reg <- tabla_heat %>% group_by(region_es) %>%
summarise(t = sum(ventas_totales)) %>% arrange(t) %>% pull(region_es)
tabla_heat <- tabla_heat %>%
mutate(producto_es = factor(producto_es, levels = orden_prod),
region_es = factor(region_es, levels = orden_reg))
g_heat <- ggplot(tabla_heat,
aes(x = producto_es, y = region_es, fill = ventas_totales,
text = paste0("Región: ", region_es,
"<br>Producto: ", producto_es,
"<br>Ventas: ", dollar(ventas_totales)))) +
geom_tile(color = "white", linewidth = 0.5) +
scale_fill_gradient(low = "#E3F2FD", high = "#0D47A1",
labels = dollar_format(prefix = "$", big.mark = ",")) +
labs(title = "Figura 2. Ventas Totales por Región y Categoría de Producto",
x = "Categoría de Producto", y = "Región", fill = "Ventas (USD)") +
theme_minimal(base_size = 12) +
theme(axis.text.x = element_text(angle = 20, hjust = 1))
ggplotly(g_heat, tooltip = "text") %>%
layout(coloraxis = list(colorbar = list(tickformat = "$,.0f")))
Interpretación: La región Oeste concentra las mayores ventas en casi todas las categorías, destacándose el calzado deportivo y urbano masculino. El Medio Oeste y el Sur presentan los menores volúmenes, lo que representa una oportunidad de expansión de mercado.
# ── Histograma de ventas totales ──────────────────────────────────────────────
media_v <- mean(datos$ventas_total, na.rm = TRUE)
mediana_v <- median(datos$ventas_total, na.rm = TRUE)
p3 <- ggplot(datos, aes(x = ventas_total)) +
geom_histogram(bins = 35, fill = "#1565C0", color = "white", alpha = 0.85) +
geom_vline(xintercept = media_v, color = "red", linetype = "dashed",
linewidth = 1.1) +
geom_vline(xintercept = mediana_v, color = "orange", linetype = "dashed",
linewidth = 1.1) +
geom_rug(alpha = 0.15, color = "black") +
annotate("text", x = media_v * 1.05, y = Inf, vjust = 2,
label = paste0("Media\n$", format(round(media_v), big.mark = ",")),
color = "red", size = 3.5) +
annotate("text", x = mediana_v * 0.92, y = Inf, vjust = 2,
label = paste0("Mediana\n$", format(round(mediana_v), big.mark = ",")),
color = "darkorange", size = 3.5) +
scale_x_continuous(labels = dollar_format(prefix = "$")) +
labs(title = "Figura 3. Distribución de las Ventas Totales por Transacción",
x = "Ventas Totales (USD)", y = "Frecuencia") +
theme_minimal(base_size = 12)
ggplotly(p3)
Interpretación: La distribución de ventas muestra una asimetría positiva (sesgo a la derecha): la mayoría de las transacciones se concentra en valores bajos/medios, pero existen transacciones de alto valor que elevan la media por encima de la mediana. Esto es típico en entornos retail donde conviven ventas individuales y ventas en volumen.
# ── Histograma del margen operativo ──────────────────────────────────────────
margen_prom <- mean(datos$margen_pct, na.rm = TRUE)
margen_sd <- sd(datos$margen_pct, na.rm = TRUE)
p4 <- ggplot(datos, aes(x = margen_pct)) +
geom_histogram(bins = 25, fill = "#6A1B9A", color = "white", alpha = 0.85) +
geom_vline(xintercept = margen_prom, color = "red",
linetype = "dashed", linewidth = 1.2) +
annotate("text",
x = margen_prom + 2,
y = Inf, vjust = 2,
label = paste0("Media: ", round(margen_prom, 1), "%"),
color = "red", size = 4) +
scale_x_continuous(labels = function(x) paste0(x, "%")) +
labs(
title = paste0("Figura 4. Distribución del Margen Operativo",
"\nPromedio: ", round(margen_prom, 1),
"% | Desv. Est.: ", round(margen_sd, 1), "%"),
x = "Margen Operativo (%)", y = "Frecuencia"
) +
theme_minimal(base_size = 12) +
theme(plot.title = element_text(size = 13, face = "bold", hjust = 0.5))
ggplotly(p4)
Interpretación: El margen operativo presenta una distribución bimodal, con concentraciones alrededor del 30–35% y del 45–50%. Esto sugiere que existen dos perfiles de rentabilidad claramente diferenciados entre productos o canales, lo que justifica un análisis segmentado más detallado.
# ── Donut chart por método de venta ──────────────────────────────────────────
rentabilidad_metodo <- datos %>%
group_by(metodo_es) %>%
summarise(utilidad = sum(utilidad_operativa, na.rm = TRUE), .groups = "drop") %>%
arrange(desc(utilidad))
plot_ly(
data = rentabilidad_metodo,
labels = ~metodo_es, values = ~utilidad,
type = "pie", hole = 0.55,
textinfo = "label+percent",
textposition = "inside",
textfont = list(size = 14, color = "white"),
hovertemplate = paste0(
"<b>%{label}</b><br>Utilidad: $%{value:,.0f}<br>",
"Participación: %{percent}<extra></extra>"
),
marker = list(
colors = c("#0D47A1", "#1976D2", "#64B5F6"),
line = list(color = "white", width = 2)
),
sort = FALSE
) %>%
layout(
title = list(text = "<b>Figura 5. Distribución de la Utilidad Operativa por Canal de Venta</b>",
x = 0.5, font = list(size = 16)),
legend = list(title = list(text = "<b>Canal de Venta</b>"))
)
Interpretación: El canal de Tienda Física concentra la mayor proporción de la utilidad operativa, seguido por En Línea y Outlet. El crecimiento del canal online representa una palanca estratégica clave, ya que opera con menores costos fijos y tiene mayor escalabilidad.
# ── Boxplot de utilidad operativa por región ─────────────────────────────────
# Ordenar regiones por mediana
orden_reg_box <- datos %>%
group_by(region_es) %>%
summarise(med = median(utilidad_operativa, na.rm = TRUE)) %>%
arrange(med) %>% pull(region_es)
datos_box <- datos %>%
mutate(region_es = factor(region_es, levels = orden_reg_box))
plot_ly(
data = datos_box,
x = ~region_es,
y = ~utilidad_operativa,
type = "box",
color = ~region_es,
colors = "Blues",
boxpoints = "outliers",
hovertemplate = "<b>%{x}</b><br>Utilidad: $%{y:,.0f}<extra></extra>"
) %>%
layout(
title = list(text = "<b>Figura 6. Distribución de la Utilidad Operativa por Región</b>",
x = 0.5),
xaxis = list(title = "<b>Región</b>"),
yaxis = list(title = "<b>Utilidad Operativa (USD)</b>",
tickprefix = "$",
separatethousands = TRUE),
showlegend = FALSE,
plot_bgcolor = "white",
paper_bgcolor = "white"
)
Interpretación: La región Oeste no solo tiene la mediana de utilidad más alta, sino también la mayor variabilidad, indicando la presencia de transacciones de muy alto valor. Las regiones Sur y Medio Oeste muestran distribuciones más comprimidas y medianas inferiores, señalando menor desempeño comercial relativo.
# ── Tabla de rentabilidad por distribuidor ───────────────────────────────────
tabla_dist <- datos %>%
group_by(Distribuidor = distribuidor) %>%
summarise(
`Ventas Totales (USD)` = dollar(sum(ventas_total, na.rm = TRUE)),
`Utilidad Operativa (USD)` = dollar(sum(utilidad_operativa, na.rm = TRUE)),
`Margen Promedio (%)` = paste0(round(mean(margen_pct, na.rm = TRUE), 1), "%"),
`Unidades Vendidas` = format(sum(unidades_vendidas, na.rm = TRUE), big.mark = ","),
.groups = "drop"
) %>%
arrange(desc(`Utilidad Operativa (USD)`))
tabla_dist %>%
kable(caption = "Tabla 2. Desempeño Comercial por Distribuidor",
align = c("l","r","r","r","r")) %>%
kable_styling(bootstrap_options = c("striped","hover","condensed"),
full_width = FALSE) %>%
column_spec(1, bold = TRUE)
| Distribuidor | Ventas Totales (USD) | Utilidad Operativa (USD) | Margen Promedio (%) | Unidades Vendidas |
|---|---|---|---|---|
| Kohl’s | $13,512,453 | $5,182,260 | 41.9% | 287,375 |
| Amazon | $10,096,987 | $3,984,432 | 41.8% | 197,990 |
| Walmart | $10,506,085 | $3,902,749 | 40.7% | 206,225 |
| West Gear | $32,409,558 | $12,196,891 | 41.8% | 625,262 |
| Foot Locker | $29,024,945 | $11,317,027 | 41.8% | 604,369 |
| Sports Direct | $24,616,622 | $10,641,609 | 44.5% | 557,640 |
# ── Dispersión: ventas totales vs margen promedio por distribuidor ────────────
dist_resumen <- datos %>%
group_by(distribuidor) %>%
summarise(
ventas_totales = sum(ventas_total, na.rm = TRUE),
margen_promedio = mean(margen_operativo, na.rm = TRUE),
utilidad_total = sum(utilidad_operativa,na.rm = TRUE),
.groups = "drop"
)
p7 <- ggplot(dist_resumen,
aes(x = ventas_totales, y = margen_promedio,
size = utilidad_total,
text = paste0(
"<b>", distribuidor, "</b><br>",
"Ventas: ", dollar(ventas_totales), "<br>",
"Margen: ", percent(margen_promedio, accuracy = 0.1), "<br>",
"Utilidad: ", dollar(utilidad_total)
))) +
geom_point(color = "#1565C0", alpha = 0.80) +
geom_text(aes(label = distribuidor), vjust = -1.2, size = 3.8, color = "black") +
scale_x_continuous(labels = dollar_format(prefix = "$")) +
scale_y_continuous(labels = percent_format(accuracy = 1)) +
scale_size_continuous(range = c(5, 18), guide = "none") +
labs(
title = "Figura 7. Ventas Totales vs Margen Operativo por Distribuidor",
subtitle = "Tamaño del punto proporcional a la Utilidad Operativa",
x = "Ventas Totales (USD)",
y = "Margen Operativo Promedio"
) +
theme_minimal(base_size = 12)
ggplotly(p7, tooltip = "text")
Interpretación: Existe una relación positiva entre volumen de ventas y utilidad total. Distribuidores como West Gear y Foot Locker combinan alto volumen y buen margen, posicionándolos como socios estratégicos prioritarios. Amazon muestra alto volumen pero con márgenes más ajustados, típico del canal online con mayor presión de precio.
# ── Correlación unidades vendidas vs ventas totales por producto ──────────────
prod_resumen <- datos %>%
group_by(producto_es) %>%
summarise(
ventas = sum(ventas_total, na.rm = TRUE),
unidades = sum(unidades_vendidas, na.rm = TRUE),
.groups = "drop"
)
corr_uv <- cor(prod_resumen$unidades, prod_resumen$ventas, use = "complete.obs")
plot_ly(prod_resumen,
x = ~unidades, y = ~ventas,
type = "scatter", mode = "markers+text",
text = ~producto_es, textposition = "top center",
marker = list(size = 12, color = "#1565C0"),
hovertemplate = paste0(
"<b>%{text}</b><br>",
"Unidades: %{x:,}<br>",
"Ventas: $%{y:,}<extra></extra>"
)
) %>%
layout(
title = list(
text = paste0("<b>Figura 8. Unidades Vendidas vs Ventas Totales por Categoría</b>",
"<br>Correlación: r = ", round(corr_uv, 2)),
x = 0.5
),
xaxis = list(title = "<b>Unidades Vendidas</b>",
separatethousands = TRUE),
yaxis = list(title = "<b>Ventas Totales (USD)</b>",
tickprefix = "$",
separatethousands = TRUE),
plot_bgcolor = "white",
paper_bgcolor = "white"
)
Interpretación: La correlación de r = 0.93 indica una asociación muy fuerte entre el número de unidades vendidas y las ventas totales por categoría. El Calzado Deportivo Masculino destaca como el producto con mayor volumen y valor acumulado, mientras que la Ropa Femenina muestra el menor desempeño en ambas dimensiones.
# ── Precio vs unidades: elasticidad aparente ──────────────────────────────────
datos_9 <- datos %>%
filter(!is.na(precio_unidad), !is.na(unidades_vendidas))
corr_pu <- cor(datos_9$precio_unidad, datos_9$unidades_vendidas,
use = "complete.obs")
g9 <- ggplot(datos_9, aes(x = precio_unidad, y = unidades_vendidas)) +
geom_point(color = "#1565C0", size = 1.8, alpha = 0.55) +
geom_smooth(method = "lm", color = "red", linewidth = 1.2, se = TRUE) +
scale_x_continuous(labels = dollar_format(prefix = "$")) +
scale_y_continuous(labels = comma_format()) +
labs(
title = paste0("Figura 9. Precio por Unidad vs Unidades Vendidas",
"\nCorrelación: r = ", round(corr_pu, 3)),
subtitle = "La línea roja representa la tendencia lineal (MCO)",
x = "Precio por Unidad (USD)",
y = "Unidades Vendidas"
) +
theme_minimal(base_size = 12)
ggplotly(g9)
Interpretación: La correlación de r = 0.266 sugiere una relación débil/moderada entre el precio y las unidades vendidas. Esto indica que Adidas tiene cierto poder de fijación de precios: los aumentos de precio no se traducen directamente en caídas proporcionales en el volumen, lo que es consistente con el posicionamiento de marca premium de la compañía.
# ── Margen por canal y categoría de producto ──────────────────────────────────
plot_ly(
data = datos,
x = ~metodo_es,
y = ~margen_pct,
color = ~producto_es,
type = "box",
boxpoints = FALSE
) %>%
layout(
title = list(text = "<b>Figura 10. Distribución del Margen Operativo por Canal y Producto</b>",
x = 0.5),
xaxis = list(title = "<b>Canal de Venta</b>"),
yaxis = list(title = "<b>Margen Operativo (%)</b>",
ticksuffix = "%"),
boxmode = "group",
legend = list(title = list(text = "<b>Producto</b>")),
plot_bgcolor = "white",
paper_bgcolor = "white"
)
Interpretación: El canal Outlet muestra los márgenes más bajos y mayor dispersión, lo que refleja estrategias de liquidación de inventario. El canal En Línea presenta márgenes competitivos y consistentes. El Calzado Deportivo Masculino mantiene márgenes superiores en todos los canales, confirmando su liderazgo estratégico.
A partir del análisis descriptivo y exploratorio realizado, se identifican los siguientes hallazgos clave:
Desempeño de Ventas:
Rentabilidad:
Relaciones entre Variables:
El análisis revela que Adidas presenta un desempeño comercial sólido en el mercado estadounidense, sustentado principalmente por el calzado masculino y la región Oeste. Sin embargo, existe una concentración de riesgo significativa: pocas categorías, regiones y distribuidores explican la mayor parte de los resultados. La empresa muestra márgenes saludables y cierto poder de fijación de precios, lo que la posiciona favorablemente para estrategias de crecimiento.
1. Diversificación Geográfica Desarrollar estrategias de marketing y distribución focalizadas en el Sur y Medio Oeste, que muestran los menores volúmenes. Esto puede incluir acuerdos con distribuidores locales y campañas de reconocimiento de marca segmentadas por región.
2. Potenciar la Categoría de Ropa Las categorías de Ropa Hombre y Ropa Mujer presentan márgenes superiores al promedio. Incrementar la inversión en marketing, ampliar el portafolio y mejorar la visibilidad en puntos de venta puede capturar valor adicional sin sacrificar rentabilidad.
3. Acelerar el Canal Digital El canal En Línea combina márgenes competitivos con menores costos fijos. Se recomienda aumentar la inversión en e-commerce, mejorar la experiencia del usuario y desarrollar capacidades de personalización y analítica de comportamiento digital.
4. Gestión Estratégica del Canal Outlet Establecer reglas claras de activación del canal Outlet para evitar canibalización de otros canales. Utilizarlo exclusivamente para liquidación de inventario de temporadas pasadas, protegiendo el posicionamiento de precio de la marca.
5. Priorizar Socios Estratégicos de Alto Valor Fortalecer la relación con West Gear y Foot Locker mediante acuerdos de exclusividad, co-inversión en puntos de venta y acceso anticipado a nuevos lanzamientos. Explorar la optimización de márgenes con Amazon a través de mejores condiciones contractuales.
6. Estrategia de Precios Diferenciada La baja elasticidad precio-demanda sugiere espacio para incrementos de precio selectivos en categorías premium como el Calzado Deportivo, sin impacto significativo en volumen. Esto permitiría mejorar el margen sin sacrificar participación de mercado.
Análisis elaborado con R 4.5.2 | Datos: DatosCaso1.xlsx | Informe listo para publicación en RPubs