Introducción

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)

Analisis de Datos

# 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

Indicadores de centralidad y dispersión

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"
  )
Medidas de tendencia central y variabilidad
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.

Indicadores Generales

# 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"
  )
Resumen general de indicadores comerciales y operativos
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.

Ventas y utilidad operativa por región

# ============================================================
# 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.

Ventas y utilidad por método de venta

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.

Ventas y utilidad por distribuidor

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.

Participacion de unidades vendidas por producto

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.

Unidades vendidas por rango de precio unitario

# ============================================================
# 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.

Ventas totales por método de venta

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.

Margen operativo por método de venta

# ============================================================
# 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.

Ventas por producto y método de venta

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.

Conclusiones

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:

  • Priorizar la expansión del canal Online, dado que combina buen volumen con el mayor margen operativo promedio en todas las líneas de producto; evaluar mayor inversión en comercio electrónico y marketing digital, especialmente para las líneas de mayor participación (Men’s Street Footwear, Women’s Apparel).
  • Revisar la estrategia comercial del canal In-store, ya que concentra volumen pero con la menor rentabilidad relativa; evaluar políticas de descuento más disciplinadas y mejoras de eficiencia operativa en tienda física.
  • Replicar en otras regiones las condiciones comerciales de South, la región con mejor margen operativo pese a no ser la de mayor volumen, para entender qué factores (mezcla de canal, de producto o de distribuidor) explican su mejor rentabilidad relativa.
  • Fortalecer el desempeño comercial de Midwest, la región más rezagada, con planes específicos que se apoyen en el aprendizaje de las combinaciones producto-canal más exitosas en otras regiones.
  • Gestionar de forma diferenciada las transacciones de muy alto valor (valores atípicos), dado que representan cerca del 8.3% de los registros y concentran una porción relevante de los ingresos; formalizar su seguimiento como cuentas o pedidos clave.
  • No basar la estrategia de precios únicamente en el volumen esperado, dado que la relación precio–unidades y precio–margen es débil; explorar otras palancas de rentabilidad (canal, distribuidor, categoría, temporada).

-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.