Adidas es una empresa global reconocida por su participación en la industria de artículos deportivos y de estilo de vida, fundada en año 1949 en Alemania, con un portafolio que incluye principalmente calzado, ropa y accesorios dirigidos tanto al rendimiento deportivo como al consumo cotidiano. La marca tiene un valor de 6.800 Millones de dolares, lo que la convierte en la segunda marca mas valiosa entre las corporaciones deportivas.
Como equipo de analistas de datos de Adidas tenemos como objetivo evaluar el desempeño comercial y financiero de distintas líneas de productos en el mercado, con el fin de comprender cómo se están desempeñando los diferentes productos y canales comerciales.
Aplicaremos técnicas de estadística descriptiva, diagnostica y visualización de datos para detectar patrones, anomalías y relaciones entre variables, facilitando una mejor interpretación de su evolución financiera.
# Cargar librerías necesarias
library(readxl)
library(dplyr)
library(ggplot2)
library(plotly)
library(knitr)
library(kableExtra)
library(tidyr)
library(tidyverse)
library(scales)
# Cargar datos desde el archivo Excel
datos_col <- read_excel("~/Maestria Finanzas/Analisis de Datos 2026-2/Caso 1/DatosCaso1.xlsx",
col_types = c("text", "text", "text",
"text", "text", "numeric", "numeric",
"numeric", "numeric", "numeric",
"text"))
# Ver las primeras filas de los datos
class(datos_col)
## [1] "tbl_df" "tbl" "data.frame"
colnames(datos_col)
## [1] "distribuidor" "region" "estado"
## [4] "ciudad" "producto" "precio_unidad"
## [7] "unidades_vendidas" "ventas_total" "utilidad_operativa"
## [10] "margen_operativo" "metodo_venta"
head(datos_col)
| 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 |
resumen_variabilidad <- datos_col %>%
summarise(across(
c(precio_unidad, unidades_vendidas, ventas_total, utilidad_operativa, margen_operativo),
list(
Media = ~mean(., na.rm = TRUE),
Mediana = ~median(., na.rm = TRUE),
Desv_estandar = ~sd(., na.rm = TRUE),
Coef_variacion = ~sd(., na.rm = TRUE) / mean(., na.rm = TRUE)
),
.names = "{.col}__{.fn}"
)) %>%
pivot_longer(everything(), names_to = c("Variable", "Medida"), names_sep = "__") %>%
pivot_wider(names_from = Medida, values_from = value) %>%
mutate(across(where(is.numeric), ~round(., 2)))
kable(
resumen_variabilidad,
format = "html",
escape = FALSE,
caption = "<div style='text-align: center;'>Medidas de tendencia central y variabilidad</div>"
) %>%
kable_styling(
bootstrap_options = c("striped", "hover", "condensed"),
full_width = TRUE
) %>%
row_spec(
0,
bold = TRUE,
color = "white",
background = "#1F4E78"
)
| Variable | Media | Mediana | Desv_estandar | Coef_variacion |
|---|---|---|---|---|
| precio_unidad | 45.22 | 45.00 | 14.71 | 0.33 |
| unidades_vendidas | 257.04 | 176.00 | 214.23 | 0.83 |
| ventas_total | 12460.25 | 7812.00 | 12716.50 | 1.02 |
| utilidad_operativa | 4896.82 | 3264.00 | 4866.45 | 0.99 |
| margen_operativo | 0.42 | 0.41 | 0.10 | 0.23 |
Las ventas totales tienen un promedio mayor que la mediana, lo que significa que hay algunas ventas muy altas que hacen que el promedio aumente. Esto indica que no todas las ventas tienen un comportamiento similar.
Además, las ventas totales y la utilidad operativa presentan una alta variación entre los diferentes registros, es decir, existen diferencias importantes en los resultados de una transacción a otra.
Por otro lado, el margen operativo es la variable más estable, ya que sus valores son más parecidos entre sí y se mantienen más cerca de su promedio.
# Crear indicadores generales
tabla_general <- datos_col %>%
summarise(
ventas_total = sum(ventas_total, na.rm = TRUE),
unidades_vendidas = sum(unidades_vendidas, na.rm = TRUE),
utilidad_operativa = sum(utilidad_operativa, na.rm = TRUE),
margen_operativo_promedio = mean(
utilidad_operativa / ventas_total * 100,
na.rm = TRUE
),
precio_promedio = ventas_total / unidades_vendidas
) %>%
mutate(
ventas_total = dollar(
ventas_total,
prefix = "US$",
big.mark = ".",
decimal.mark = ",",
accuracy = 1
),
unidades_vendidas = format(
unidades_vendidas,
big.mark = ".",
decimal.mark = ",",
scientific = FALSE
),
utilidad_operativa = dollar(
utilidad_operativa,
prefix = "US$",
big.mark = ".",
decimal.mark = ",",
accuracy = 1
),
margen_operativo_promedio = paste0(
format(
round(margen_operativo_promedio, 2),
decimal.mark = ",",
nsmall = 2
),
"%"
),
precio_promedio = dollar(
precio_promedio,
prefix = "US$",
big.mark = ".",
decimal.mark = ",",
accuracy = 1
)
) %>%
# Convertir la tabla a formato vertical
pivot_longer(
cols = everything(),
names_to = "indicador",
values_to = "valor"
) %>%
mutate(
indicador = recode(
indicador,
ventas_total = "Ventas totales",
unidades_vendidas = "Unidades vendidas",
utilidad_operativa = "Utilidad operacional",
margen_operativo_promedio = "Margen operativo promedio",
precio_promedio = "Precio promedio"
)
)
# Mostrar tabla vertical
kable(
tabla_general,
format = "html",
escape = FALSE,
align = c("l", "r"),
col.names = c("Indicador", "Resultado"),
caption = "Resumen general de indicadores comerciales y operativos"
) %>%
kable_styling(
bootstrap_options = c(
"striped",
"hover",
"condensed",
"responsive"
),
full_width = FALSE,
position = "center",
font_size = 14
) %>%
row_spec(
0,
bold = TRUE,
color = "white",
background = "#1F4E78",
align = "center"
) %>%
column_spec(
1,
bold = TRUE,
color = "#1F4E78",
width = "7cm"
) %>%
column_spec(
2,
bold = TRUE,
color = "#333333",
width = "6cm"
)
| Indicador | Resultado |
|---|---|
| Ventas totales | US$120.166.650 |
| Unidades vendidas | 2.478.861 |
| Utilidad operacional | US$47.224.968 |
| Margen operativo promedio | 39,30% |
| Precio promedio | US$48 |
En esta tabla se presenta un resumen de los principales variables financieras. Lo mas relevante es que la empresa tuvo un margen operativo promedio del 39.30%, lo que significa que por cada 100 pesos vendidos, generó cerca de 39 pesos de utilidad operacional.
# ============================================================
# RESUMEN DE VENTAS Y UTILIDAD OPERATIVA POR REGIÓN
# ============================================================
resumen_metodo <- datos_col %>%
group_by(region) %>%
summarise(
ventas_total = sum(ventas_total, na.rm = TRUE),
utilidad_operativa = sum(utilidad_operativa, na.rm = TRUE),
.groups = "drop"
) %>%
mutate(
# Convertir los valores a millones de dólares
ventas_total = ventas_total / 1000000,
utilidad_operativa = utilidad_operativa / 1000000
) %>%
pivot_longer(
cols = c(ventas_total, utilidad_operativa),
names_to = "indicador",
values_to = "valor"
) %>%
mutate(
indicador = recode(
indicador,
ventas_total = "Ventas totales",
utilidad_operativa = "Utilidad operativa"
)
)
# ============================================================
# GRÁFICO DE BARRAS AGRUPADAS
# ============================================================
ggplot(
resumen_metodo,
aes(
x = region,
y = valor,
fill = indicador
)
) +
geom_col(
position = position_dodge(width = 0.75),
width = 0.65
) +
geom_text(
aes(
label = paste0(
"US$ ",
format(
round(valor, 2),
decimal.mark = ",",
big.mark = ".",
nsmall = 2
),
" M"
)
),
position = position_dodge(width = 0.75),
vjust = -0.35,
size = 2.5,
color = "#263238",
fontface = "bold"
) +
scale_fill_manual(
values = c(
"Ventas totales" = "#164E70",
"Utilidad operativa" = "#5B9DB5"
)
) +
scale_y_continuous(
labels = function(x) {
paste0(
"US$ ",
format(
x,
decimal.mark = ",",
big.mark = ".",
nsmall = 0
),
" M"
)
},
expand = expansion(mult = c(0, 0.15))
) +
labs(
title = "Figura 1. Ventas y utilidad operativa por región",
subtitle = "Valores acumulados expresados en millones de dólares estadounidenses",
x = "Región",
y = "Valor financiero (US$ millones)",
fill = "Indicador"
) +
theme_minimal(base_family = "Arial") +
theme(
panel.grid = element_blank(),
plot.title = element_text(
size = 16,
face = "bold",
color = "#1F4E78",
hjust = 0.5
),
plot.subtitle = element_text(
size = 11,
color = "#5B6770",
hjust = 0.5
),
axis.title = element_text(
size = 11,
face = "bold",
color = "#263238"
),
axis.text = element_text(
size = 10,
color = "#374151"
),
legend.position = "top",
legend.title = element_text(
face = "bold",
color = "#263238"
),
legend.text = element_text(
size = 10,
color = "#374151"
)
)
la región West concentra el mayor volumen de ventas y de utilidad operativa, seguida de Northeast, mientras que Midwest es la región con menor desempeño comercial. Sin embargo, un mayor volumen de ventas no siempre implica un mayor margen operacional, como lo es para el caso de South, que a pesar de que no presenta el valor más alto en ventas,es la region con el mejor desempeño en términos de rentabilidad.
Una posible explicación de que South tenga el mayor margen operativo es que sus costos y gastos operativos sean menores en relación con sus ventas. Es decir, aunque la región no sea la que más vende, podría estar administrando sus recursos de una manera más eficiente.
library(dplyr)
library(tidyr)
library(ggplot2)
# ============================================================
# RESUMEN DE VENTAS Y UTILIDAD POR MÉTODO DE VENTA
# ============================================================
resumen_metodo <- datos_col %>%
group_by(metodo_venta) %>%
summarise(
ventas_total = sum(ventas_total, na.rm = TRUE),
utilidad_operativa = sum(utilidad_operativa, na.rm = TRUE),
.groups = "drop"
) %>%
mutate(
# Convertir los valores a millones de dólares
ventas_total = ventas_total / 1000000,
utilidad_operativa = utilidad_operativa / 1000000
) %>%
pivot_longer(
cols = c(ventas_total, utilidad_operativa),
names_to = "indicador",
values_to = "valor"
) %>%
mutate(
indicador = recode(
indicador,
ventas_total = "Ventas totales",
utilidad_operativa = "Utilidad operativa"
)
)
# ============================================================
# GRÁFICO DE BARRAS AGRUPADAS
# ============================================================
ggplot(
resumen_metodo,
aes(
x = metodo_venta,
y = valor,
fill = indicador
)
) +
geom_col(
position = position_dodge(width = 0.75),
width = 0.65
) +
geom_text(
aes(
label = paste0(
"US$ ",
format(
round(valor, 2),
decimal.mark = ",",
big.mark = ".",
nsmall = 2
),
" M"
)
),
position = position_dodge(width = 0.75),
vjust = -0.35,
size = 3.8,
color = "#263238",
fontface = "bold"
) +
scale_fill_manual(
values = c(
"Ventas totales" = "#164E70",
"Utilidad operativa" = "#5B9DB5"
)
) +
scale_y_continuous(
labels = function(x) {
paste0(
"US$ ",
format(
x,
decimal.mark = ",",
big.mark = ".",
nsmall = 1
),
" M"
)
},
expand = expansion(mult = c(0, 0.15))
) +
labs(
title = "Figura 2. Ventas y utilidad operativa por método de venta",
subtitle = "Valores acumulados expresados en millones de dólares estadounidenses",
x = "Método de venta",
y = "Valor financiero (US$ millones)",
fill = "Indicador"
) +
theme_minimal(base_family = "Arial") +
theme(
# Eliminar las líneas del fondo
panel.grid = element_blank(),
plot.title = element_text(
size = 16,
face = "bold",
color = "#1F4E78",
hjust = 0.5
),
plot.subtitle = element_text(
size = 11,
color = "#5B6770",
hjust = 0.5
),
axis.title = element_text(
size = 11,
face = "bold",
color = "#263238"
),
axis.text = element_text(
size = 10,
color = "#374151"
),
legend.position = "top",
legend.title = element_text(
face = "bold",
color = "#263238"
),
legend.text = element_text(
size = 10,
color = "#374151"
)
)
El canal Online se posiciona como el principal motor comercial y de rentabilidad ya que presenta el desempeño más atractivo al combinar el mayor volumen de ventas con la mayor utilidad operativa y un margen superior en 7,7 puntos porcentuales frente al canal In-store.
Esta rentabilidad elevada puede obedecer principalmente a menores costos asociados a la infraestructura fisica, reducción de gastos de personal y optimización de la cadena de suministro. Adicional a ello, este canal tiene un mayor alcance de accesibilidad para los consumidores, al permitir realizar compras de manera flexible, independientemente de la ubicación y el horario.
library(dplyr)
library(tidyr)
library(ggplot2)
# ============================================================
# RESUMEN POR DISTRIBUIDOR Y CÁLCULO DEL MARGEN OPERATIVO
# ============================================================
resumen_distribuidor_base <- datos_col %>%
group_by(distribuidor) %>%
summarise(
ventas_total = sum(ventas_total, na.rm = TRUE),
utilidad_operativa = sum(utilidad_operativa, na.rm = TRUE),
.groups = "drop"
) %>%
mutate(
margen_operativo = if_else(
ventas_total != 0,
utilidad_operativa / ventas_total * 100,
NA_real_
)
)
# ============================================================
# DATOS EN FORMATO LARGO
# ============================================================
resumen_distribuidor <- resumen_distribuidor_base %>%
pivot_longer(
cols = c(ventas_total, utilidad_operativa),
names_to = "indicador",
values_to = "valor"
) %>%
mutate(
indicador = recode(
indicador,
ventas_total = "Ventas totales",
utilidad_operativa = "Utilidad operativa"
),
# Convertir valores a millones
valor_millones = valor / 1000000,
# Etiquetas en millones de dólares estadounidenses
etiqueta = paste0(
"US$ ",
format(
round(valor_millones, 1),
decimal.mark = ",",
big.mark = ".",
nsmall = 1,
scientific = FALSE
),
" M"
)
)
# ============================================================
# GRÁFICO DE BARRAS AGRUPADAS
# ============================================================
ggplot(
resumen_distribuidor,
aes(
x = distribuidor,
y = valor_millones,
fill = indicador
)
) +
geom_col(
position = position_dodge(width = 0.75),
width = 0.55
) +
geom_text(
aes(label = etiqueta),
position = position_dodge(width = 0.75),
vjust = -0.35,
size = 2.5,
color = "#1F2937",
fontface = "bold"
) +
scale_fill_manual(
values = c(
"Ventas totales" = "#164E70",
"Utilidad operativa" = "#5B9DB5"
)
) +
scale_y_continuous(
labels = function(x) {
paste0(
"US$ ",
format(
x,
decimal.mark = ",",
big.mark = ".",
nsmall = 1,
scientific = FALSE
),
" M"
)
},
expand = expansion(mult = c(0, 0.15))
) +
labs(
title = "Figura 3. Ventas y utilidad operativa por distribuidor",
subtitle = "Valores acumulados expresados en millones de dólares estadounidenses",
x = "Distribuidor",
y = "Valor financiero (US$ millones)",
fill = "Indicador"
) +
theme_minimal(base_family = "Arial") +
theme(
panel.grid = element_blank(),
plot.title = element_text(
size = 16,
face = "bold",
color = "Black",
hjust = 0.5
),
plot.subtitle = element_text(
size = 11,
color = "#4B5563",
hjust = 0.5
),
axis.title = element_text(
size = 11,
face = "bold",
color = "#1F2937"
),
axis.text = element_text(
size = 10,
color = "#374151"
),
axis.text.x = element_text(
angle = 0,
hjust = 0.5,
vjust = 1
),
legend.position = "top",
legend.title = element_text(
face = "bold",
color = "#1F2937"
),
legend.text = element_text(
color = "#374151"
)
)
West Gear se destaca por presentar el mayor nivel de ventas y utilidad operacional, con aproximadamente $32 M y $12 M, respectivamente; sin embargo, su margen operativo cercano al 38% indica que su liderazgo se debe principalmente al volumen de ventas y no a una mayor eficiencia. Por su parte, Sports Direct presenta el mejor desempeño en términos de eficiencia, ya que con aproximadamente $24 M en ventas genera $10,6 M de utilidad, alcanzando el margen más alto de la muestra, cercano al 44%, esto podría estar relacionado con un mejor mix de productos, mayor poder de negociación, una estructura de costos más eficiente o menores gastos operativos relativos. Finalmente, Foot Locker combina un alto nivel de ventas, cercano a $29 M, con una utilidad de aproximadamente $11 M, similar a West Gear, aunque con un margen ligeramente menor, mostrando un desempeño sólido tanto en escala como en rentabilidad.
library(dplyr)
library(plotly)
# ============================================================
# RESUMIR UNIDADES VENDIDAS POR PRODUCTO
# ============================================================
unidades_producto <- datos_col %>%
group_by(producto) %>%
summarise(
total_unidades = sum(unidades_vendidas, na.rm = TRUE),
ventas_totales = sum(ventas_total, na.rm = TRUE),
.groups = "drop"
) %>%
mutate(
participacion_ventas =
ventas_totales / sum(ventas_totales) * 100
) %>%
arrange(desc(total_unidades))
# ============================================================
# PALETA CORPORATIVA DE AZULES CON MAYOR CONTRASTE
# ============================================================
colores_azules <- c(
"#082B4C", # Azul marino oscuro
"#0B4F71", # Azul petróleo
"#126A91", # Azul profundo
"#1884AD", # Azul medio oscuro
"#299EC2", # Azul medio
"#55B6D1", # Azul claro
"#86CFE0", # Azul celeste
"#C2E7EF" # Azul muy claro
)
# Repetir colores si hay más productos
colores_azules <- rep(
colores_azules,
length.out = nrow(unidades_producto)
)
# ============================================================
# GRÁFICO DE TORTA
# ============================================================
plot_ly(
unidades_producto,
labels = ~producto,
values = ~total_unidades,
type = "pie",
textinfo = "percent",
textposition = "inside",
insidetextorientation = "radial",
hovertemplate = paste(
"<b>%{label}</b><br>",
"Unidades vendidas: %{value:,}<br>",
"Participación: %{percent}<extra></extra>"
),
marker = list(
colors = colores_azules,
line = list(
color = "#FFFFFF",
width = 2
)
)
) %>%
layout(
title = list(
text = "<b>Figura 4. Participación de unidades vendidas por producto</b>",
font = list(
color = "#082B4C",
size = 24,
family = "Arial"
),
x = 0.5,
xanchor = "center"
),
showlegend = TRUE,
legend = list(
title = list(
text = "<b>Productos</b>"
),
orientation = "v",
x = 1,
y = 0.5,
font = list(
size = 11,
color = "#263238"
)
),
margin = list(
l = 10,
r = 220,
t = 100,
b = 10
),
paper_bgcolor = "#FFFFFF",
plot_bgcolor = "#FFFFFF"
)
La distribución de unidades vendidas evidencia un portafolio relativamente diversificado, aunque con una mayor concentración en las categorías masculinas, que representan aproximadamente el 53.9% del volumen total. Men’s Street Footwear constituye la principal categoría, con una participación del 23.9% por lo que podría considerarse el producto de mayor volumen y tener especial importancia en las estrategias comerciales. Mientras que las demás categorías presentan participaciones entre el 12% y el 18%. Estas variaciones pueden estar relacionadas con diferencias en las preferencias de los consumidores, precios, promociones, disponibilidad de inventario, estacionalidad y estrategia comercial.
# ============================================================
# CREAR RESUMEN POR RANGO DE PRECIO
# ============================================================
# Se conserva datos_col como la base original y se crea
# un nuevo objeto llamado resumen_precios.
resumen_precios <- datos_col %>%
mutate(
rango_precio = case_when(
precio_unidad >= 0 & precio_unidad < 20 ~ "US$0-20",
precio_unidad >= 20 & precio_unidad < 40 ~ "US$20-40",
precio_unidad >= 40 & precio_unidad < 60 ~ "US$40-60",
precio_unidad >= 60 & precio_unidad < 80 ~ "US$60-80",
precio_unidad >= 80 & precio_unidad < 100 ~ "US$80-100",
precio_unidad >= 100 & precio_unidad < 120 ~ "US$100-120",
precio_unidad >= 120 ~ "US$120+",
TRUE ~ NA_character_
)
) %>%
filter(!is.na(rango_precio)) %>%
group_by(rango_precio) %>%
summarise(
unidades_vendidas = sum(unidades_vendidas, na.rm = TRUE),
precio_promedio = mean(precio_unidad, na.rm = TRUE),
.groups = "drop"
) %>%
mutate(
# Conversión de unidades a miles
unidades_miles = unidades_vendidas / 1000,
rango_precio = factor(
rango_precio,
levels = c(
"US$0-20",
"US$20-40",
"US$40-60",
"US$60-80",
"US$80-100",
"US$100-120",
"US$120+"
)
)
)
# ============================================================
# GRÁFICO DE BARRAS EN MILES
# ============================================================
grafico_precios <- ggplot(
resumen_precios,
aes(
x = rango_precio,
y = unidades_miles,
fill = rango_precio
)
) +
geom_col(
color = "#082B4C",
linewidth = 0.4,
alpha = 1,
width = 0.65
) +
geom_text(
aes(
label = paste0(
format(
round(unidades_miles, 1),
big.mark = ".",
decimal.mark = ","
),
" mil"
)
),
vjust = -0.6,
size = 4.2,
fontface = "bold",
color = "#163A5F"
) +
geom_line(
aes(group = 1),
color = "#B3E5FC",
linewidth = 1.3,
linetype = "dashed"
) +
geom_point(
color = "#0B1F33",
size = 3.5
) +
labs(
title = "Unidades vendidas por rango de precio unitario",
subtitle = "Total de unidades vendidas expresado en miles",
x = "Rango de precio unitario (US$)",
y = "Unidades vendidas (miles)"
) +
scale_fill_manual(
values = c(
"US$0-20" = "#B3E5FC",
"US$20-40" = "#4FC3F7",
"US$40-60" = "#03A9F4",
"US$60-80" = "#0288D1",
"US$80-100" = "#0277BD",
"US$100-120" = "#01579B",
"US$120+" = "#003C6C"
),
guide = "none"
) +
scale_y_continuous(
labels = label_number(
big.mark = ".",
decimal.mark = ",",
accuracy = 1
),
limits = c(
0,
max(resumen_precios$unidades_miles, na.rm = TRUE) * 1.2
),
expand = expansion(mult = c(0, 0.02))
) +
theme_minimal() +
theme(
plot.title = element_text(
face = "bold",
size = 18,
hjust = 0.5,
color = "#082B4C",
margin = margin(b = 8)
),
plot.subtitle = element_text(
size = 11,
hjust = 0.5,
color = "#496A85",
margin = margin(b = 15)
),
axis.title = element_text(
face = "bold",
size = 11,
color = "#163A5F"
),
axis.text = element_text(
size = 10,
color = "#29465B"
),
# Quitar todas las líneas del fondo
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
# Fondo blanco
panel.background = element_rect(
fill = "white",
colour = NA
),
plot.background = element_rect(
fill = "white",
colour = NA
),
plot.margin = margin(20, 20, 20, 20)
)
# Mostrar el gráfico
grafico_precios
Las ventas presentan una fuerte concentración en los rangos de precio unitario entre US$20 y US$80, los cuales representan aproximadamente el 94.47% de las unidades comercializadas, una de las posibles causas puede ser una mayor disponibilidad del portafolio o mayor sensibilidad del consumidor al precio. El rango de US$40-US$60 constituye el principal segmento de demanda, concentrando cerca del 49.20 % de las unidades vendidas, por lo tanto debe mantenerse como segmento estrategico. Este comportamiento evidencia una mayor aceptación de productos de precio medio, mientras que los productos de precio superior a US$80 presentan una participación considerablemente menor, debido a la baja demanda en segmentos superiores ya que podría reflejar una limitada disposición a pagar o una insuficiente diferenciación de la propuesta premium.
library(ggplot2)
library(plotly)
# ============================================================
# BOXPLOT INTERACTIVO DE VENTAS TOTALES POR MÉTODO DE VENTA
# ============================================================
grafico <- ggplot(
datos_col,
aes(
x = metodo_venta,
y = ventas_total,
fill = metodo_venta,
text = paste(
"<b>Método:</b>", metodo_venta,
"<br><b>Ventas totales:</b>", ventas_total,
"<br><b>Producto:</b>", producto,
"<br><b>Ciudad:</b>", ciudad,
"<br><b>Distribuidor:</b>", distribuidor
)
)
) +
geom_boxplot(
color = "#003C6C",
linewidth = 0.8,
alpha = 0.95,
width = 0.6,
outlier.color = "#001F3F",
outlier.fill = "#00A6E8",
outlier.shape = 21,
outlier.size = 3
) +
# Gama de azules vivos
scale_fill_manual(
values = c(
"Online" = "#00A6E8",
"Outlet" = "#0077B6",
"In-store" = "#003C6C"
)
) +
labs(
title = "Figura 6. Distribución de ventas totales por método",
subtitle = "Comparación de las ventas según el canal comercial",
x = "Método de venta",
y = "Ventas totales"
) +
theme_minimal(base_family = "Arial") +
theme(
# Eliminar completamente las líneas del fondo
panel.grid = element_blank(),
# Fondo blanco
panel.background = element_rect(
fill = "white",
colour = NA
),
plot.background = element_rect(
fill = "white",
colour = NA
),
# Título grande, centrado y en negrita
plot.title = element_text(
size = 18,
face = "bold",
color = "Black",
hjust = 0.5,
family = "Arial",
margin = margin(b = 8)
),
# Subtítulo centrado
plot.subtitle = element_text(
size = 12,
color = "#0077B6",
hjust = 0.5,
family = "Arial",
margin = margin(b = 15)
),
axis.title = element_text(
size = 11,
face = "bold",
color = "#003C6C",
family = "Arial"
),
axis.text = element_text(
size = 10,
color = "#1F2937",
family = "Arial"
),
axis.text.x = element_text(
angle = 0,
hjust = 0.5,
family = "Arial"
),
legend.position = "none",
plot.margin = margin(20, 20, 20, 20)
)
# ============================================================
# CONVERTIR EL BOXPLOT EN GRÁFICO INTERACTIVO
# ============================================================
ggplotly(
grafico,
tooltip = "text"
)
Las ventas realizadas en tiendas físicas (In-store) presentan el mayor valor por transacción, sin embargo, las compras tienden a concentrar un mayor valor por operacion, una de las posibles causas puede ser porque el cliente tiene contacto directo con el producto y puede recibir asesoramiento comercial, lo que hace que el cliente pueda adquirir productos complementarios y este incremente el valor de la venta final.
Online registra las ventas por transaccion más bajas, este comportamiento puede estar relacionado con la facilidad de realizar compras pequeñas desde cualquier lugar, la frecuente utilización de ofertas digitales y la ausencia de compras complementarias que suelen producirse en las tiendas físicas. Además, los costos de envío o los valores mínimos para acceder al despacho gratuito pueden influir en la cantidad y el valor de los productos incluidos en cada pedido. Sin embargo, el canal Online también presenta algunas transacciones atípicamente altas. Estas operaciones podrían corresponder a compras corporativas, pedidos de clientes mayoristas, compras para eventos o acumulación de varios productos en una sola orden. Por esta razón, la mediana resulta más representativa que el promedio para describir el comportamiento habitual del canal.
Finalmente, Outlet muestra un comportamiento intermedio, posiblemente asociado con consumidores sensibles al precio y con compras condicionadas por la disponibilidad de inventario o las liquidaciones.
# ============================================================
# BOXPLOT DEL MARGEN OPERATIVO POR MÉTODO DE VENTA
# ============================================================
grafico_margen_metodo <- ggplot(
datos_col,
aes(
x = reorder(
metodo_venta,
margen_operativo,
FUN = median,
na.rm = TRUE
),
y = margen_operativo,
fill = metodo_venta,
text = paste(
"<b>Método:</b>", metodo_venta,
"<br><b>Margen operativo:</b>",
percent(margen_operativo, accuracy = 0.1)
)
)
) +
geom_boxplot(
width = 0.6,
alpha = 0.95,
color = "#003C6C",
linewidth = 0.8,
outlier.color = "#001F3F",
outlier.fill = "#00A6E8",
outlier.shape = 21,
outlier.size = 2.8,
show.legend = FALSE
) +
scale_fill_manual(
values = c(
"Online" = "#00A6E8",
"Outlet" = "#0077B6",
"In-store" = "#003C6C"
)
) +
scale_y_continuous(
labels = label_percent(accuracy = 1),
expand = expansion(mult = c(0.02, 0.08))
) +
coord_flip() +
labs(
title = "Figura 7. Distribución del margen operativo por método",
subtitle = "Comparación del margen operativo según el canal comercial",
x = NULL,
y = "Margen operativo"
) +
theme_minimal(base_family = "Arial") +
theme(
# Eliminar las líneas del fondo
panel.grid = element_blank(),
# Fondo blanco
panel.background = element_rect(
fill = "white",
colour = NA
),
plot.background = element_rect(
fill = "white",
colour = NA
),
# Título grande, centrado y en negrita
plot.title = element_text(
size = 16,
face = "bold",
color = "Black",
hjust = 0.5,
family = "Arial",
margin = margin(b = 8)
),
# Subtítulo centrado
plot.subtitle = element_text(
size = 11,
color = "#0077B6",
face = "bold",
hjust = 0.5,
family = "Arial",
margin = margin(b = 15)
),
axis.title = element_text(
size = 11,
face = "bold",
color = "#003C6C",
family = "Arial"
),
axis.text = element_text(
size = 10,
face = "bold",
color = "#1F2937",
family = "Arial"
),
axis.text.y = element_text(
size = 10,
face = "bold",
color = "#1F2937",
family = "Arial"
),
plot.margin = margin(20, 20, 20, 20)
)
# ============================================================
# CONVERTIR EL BOXPLOT EN GRÁFICO INTERACTIVO
# ============================================================
ggplotly(
grafico_margen_metodo,
tooltip = "text"
)
El canal Online presenta el margen operativo típico más alto y, por lo tanto es el canal con mayor rentabilidad,esto puede ser por menores costos operativos, mayor eficiencia comercial, mix de productos diferentes, lo cual concluye que online vende menos por transaccion, pero es el canal mas rentable en terminos de margen, sin embargo, todavia no esta alcanzando un volumen de ventas suficientemente alto. In-store registra el margen mediano más bajo, posiblemente debido a sus mayores costos fijos, tales como alquiler de establecimiento, nomina operativa, servicios publicos, mantenimiento, entre otros. Mientras que Outlet presenta un comportamiento intermedio y más condicionado por descuentos y liquidaciones.
library(dplyr)
library(tidyr)
library(plotly)
# ============================================================
# RESUMIR LAS VENTAS POR PRODUCTO Y MÉTODO DE VENTA
# ============================================================
heatmap_producto_metodo <- datos_col %>%
group_by(producto, metodo_venta) %>%
summarise(
ventas_total = sum(ventas_total, na.rm = TRUE),
.groups = "drop"
) %>%
pivot_wider(
names_from = metodo_venta,
values_from = ventas_total,
values_fill = 0
)
# Conservar los nombres de los productos
productos <- heatmap_producto_metodo$producto
# Convertir las ventas en una matriz numérica
matriz_heatmap <- heatmap_producto_metodo %>%
select(-producto) %>%
as.matrix()
# ============================================================
# CREAR EL MAPA DE CALOR
# ============================================================
grafico_heatmap <- plot_ly(
x = colnames(matriz_heatmap),
y = productos,
z = matriz_heatmap,
type = "heatmap",
colorscale = list(
list(0.00, "#D6F0FF"),
list(0.20, "#7DD3FC"),
list(0.40, "#38BDF8"),
list(0.60, "#0284C7"),
list(0.80, "#0369A1"),
list(1.00, "#082F49")
),
colorbar = list(
title = list(
text = "<b>Ventas</b>",
font = list(
family = "Arial",
size = 12,
color = "#082F49"
)
),
tickprefix = "US$",
tickformat = ",.0f",
tickfont = list(
family = "Arial",
size = 10,
color = "#374151"
)
),
hovertemplate = paste(
"<b>Producto:</b> %{y}<br>",
"<b>Método de venta:</b> %{x}<br>",
"<b>Ventas:</b> $%{z:,.0f}<extra></extra>"
)
) %>%
layout(
title = list(
text = "<b>Figura 8.Heatmap de ventas por producto y método de venta</b>",
font = list(
color = "#082F49",
size = 19,
family = "Arial"
),
x = 0.5,
xanchor = "center"
),
xaxis = list(
title = list(
text = "<b>Método de venta</b>",
font = list(
family = "Arial",
size = 13,
color = "#082F49"
)
),
tickfont = list(
family = "Arial",
size = 11,
color = "#374151"
),
showgrid = FALSE,
zeroline = FALSE
),
yaxis = list(
title = list(
text = "<b>Producto</b>",
font = list(
family = "Arial",
size = 13,
color = "#082F49"
)
),
tickfont = list(
family = "Arial",
size = 11,
color = "#374151"
),
showgrid = FALSE,
zeroline = FALSE
),
paper_bgcolor = "#FFFFFF",
plot_bgcolor = "#FFFFFF",
margin = list(
l = 160,
r = 100,
t = 100,
b = 80
)
)
# ============================================================
# MOSTRAR EL MAPA DE CALOR
# ============================================================
grafico_heatmap
las ventas presentan diferencias importantes según el producto y el método de venta. Men’s Street Footwear destaca como la categoría de mayor rendimiento, principalmente en el canal online, mientras que Men’s Apparel y Women’s Athletic Footwear muestran un desempeño relativamente menor. Estas diferencias podrían estar relacionadas con las preferencias de los consumidores, la disponibilidad de productos, las estrategias promocionales y el creciente uso del comercio electrónico.
El análisis descriptivo y diagnóstico muestra una compañía con un portafolio de producto diversificado y un desempeño de ventas fuertemente influenciado por la región y, sobre todo, por el canal de venta. La rentabilidad (margen operativo) no está determinada principalmente por el precio, sino por cómo y dónde se vende el producto.
Se evidenció que el canal Online constituye el principal motor comercial y financiero de la empresa, al concentrar tanto el mayor volumen de ventas como el mayor margen. La concentración de la demanda en productos con precios entre USD 40 y USD 60 indica que este rango representa un punto de equilibrio atractivo entre volumen y rentabilidad. Dentro del portafolio, Men’s Street Footwear destaca como el principal producto estrategico, Mientras que West se posiciona como la región con mayor generación de ventas.
A partir de estos hallazgos se proponen las siguientes recomendaciones de negocio:
-Asegurar su disponibilidad, priorizarlo en las campañas digitales y optimizar su nivel de inventario para minimizar pérdidas por quiebres de stock. Dado su alto nivel de demanda, se debe evaluar adicionalmente la capacidad de mantener o incrementar el margen sin afectar significativamente el volumen.
La estrategia financiera debería evolucionar desde una gestión basada en volumen hacia una gestión basada en rentabilidad incremental. Los recursos deben concentrarse en las combinaciones producto–canal–región que demuestren simultáneamente alta demanda y capacidad de generación de margen, mientras que los segmentos de bajo desempeño deben someterse a procesos de optimización antes de recibir nuevas inversiones.
La implementación de las recomendaciones permitiría concentrar los recursos en los segmentos con mayor capacidad de generación de valor, Como consecuencia, se esperaría un incremento del margen total, una mayor eficiencia comercial y una reducción de recursos destinados a segmentos de bajo rendimiento.