1. Contexto y Objetivo

En este apartado se analizan las ventas de Adidas en Estados Unidos por distribuidor, región, producto y método de venta. El propósito es identificar dónde se genera el dinero, dónde se gana más por cada dólar vendido y dónde hay oportunidades de mejora, para apoyar la toma de decisiones estratégicas de la Junta Directiva.

2. Carga y Revisión de los Datos

# Opción A: el archivo está en la misma carpeta del proyecto
datos <- read_excel("C:/Users/jesusd.perdomo/Downloads/DatosCaso1 (2).xlsx")

# Opción B (si no lo encuentra): datos <- read_excel(file.choose())

# La columna ventas_total es una fórmula en Excel; la recalculamos por seguridad
datos <- datos %>%
  mutate(ventas_total = precio_unidad * unidades_vendidas,
         across(c(distribuidor, region, estado, ciudad, producto, metodo_venta), as.factor))

dim(datos)
## [1] 9648   11
glimpse(datos)
## Rows: 9,648
## Columns: 11
## $ distribuidor       <fct> Foot Locker, Foot Locker, Foot Locker, Foot Locker,…
## $ region             <fct> Northeast, Northeast, Northeast, Northeast, Northea…
## $ estado             <fct> New York, New York, New York, New York, New York, N…
## $ ciudad             <fct> New York, New York, New York, New York, New York, N…
## $ producto           <fct> Men's Street Footwear, Men's Athletic Footwear, Wom…
## $ precio_unidad      <dbl> 50, 50, 40, 45, 60, 50, 50, 50, 40, 45, 60, 50, 50,…
## $ unidades_vendidas  <dbl> 1200, 1000, 1000, 850, 900, 1000, 1250, 900, 950, 8…
## $ ventas_total       <dbl> 60000, 50000, 40000, 38250, 54000, 50000, 62500, 45…
## $ utilidad_operativa <dbl> 30000.00, 15000.00, 14000.00, 13387.50, 16200.00, 1…
## $ margen_operativo   <dbl> 0.50, 0.30, 0.35, 0.35, 0.30, 0.25, 0.50, 0.30, 0.3…
## $ metodo_venta       <fct> In-store, In-store, In-store, In-store, In-store, I…
# Calidad de datos
colSums(is.na(datos))          # valores faltantes
##       distribuidor             region             estado             ciudad 
##                  0                  0                  0                  0 
##           producto      precio_unidad  unidades_vendidas       ventas_total 
##                  0                  0                  0                  0 
## utilidad_operativa   margen_operativo       metodo_venta 
##                  0                  0                  0
sum(duplicated(datos))         # filas idénticas (pueden ser transacciones repetidas legítimas)
## [1] 262
summary(datos %>% select(where(is.numeric)))
##  precio_unidad    unidades_vendidas  ventas_total   utilidad_operativa
##  Min.   :  7.00   Min.   :   0.0    Min.   :    0   Min.   :    0     
##  1st Qu.: 35.00   1st Qu.: 106.0    1st Qu.: 4065   1st Qu.: 1753     
##  Median : 45.00   Median : 176.0    Median : 7804   Median : 3263     
##  Mean   : 45.22   Mean   : 256.9    Mean   :12455   Mean   : 4895     
##  3rd Qu.: 55.00   3rd Qu.: 350.0    3rd Qu.:15864   3rd Qu.: 6192     
##  Max.   :110.00   Max.   :1275.0    Max.   :82500   Max.   :39000     
##  margen_operativo
##  Min.   :0.100   
##  1st Qu.:0.350   
##  Median :0.410   
##  Mean   :0.423   
##  3rd Qu.:0.490   
##  Max.   :0.800

Nota: la base no tiene variable de fecha, por lo que no se analiza evolución en el tiempo.

3. Resumen Ejecutivo (KPIs)

kpis <- datos %>%
  summarise(
    `Ventas totales (USD)`     = sum(ventas_total),
    `Utilidad operativa (USD)` = sum(utilidad_operativa),
    `Margen operativo global`  = sum(utilidad_operativa) / sum(ventas_total),
    `Unidades vendidas`        = sum(unidades_vendidas),
    `Precio promedio (USD)`    = mean(precio_unidad)
  )
kable(kpis, digits = 2, format.args = list(big.mark = ","))
Ventas totales (USD) Utilidad operativa (USD) Margen operativo global Unidades vendidas Precio promedio (USD)
120,166,650 47,224,968 0.39 2,478,861 45.22

Para lo siguiente, definimos una función que resume cualquier dimensión. Importante: el margen se calcula como utilidad total / ventas totales (ponderado), no como promedio de la columna margen_operativo.

resumen_por <- function(df, variable) {
  df %>%
    group_by({{ variable }}) %>%
    summarise(ventas   = sum(ventas_total),
              utilidad = sum(utilidad_operativa),
              unidades = sum(unidades_vendidas),
              margen   = utilidad / ventas,
              .groups = "drop") %>%
    mutate(part_ventas = ventas / sum(ventas)) %>%
    arrange(desc(ventas))
}

4. Desempeño por Distribuidor

r_dist <- resumen_por(datos, distribuidor)
kable(r_dist, digits = 3, format.args = list(big.mark = ","))
distribuidor ventas utilidad unidades margen part_ventas
West Gear 32,409,558 12,196,891 625,262 0.376 0.270
Foot Locker 29,024,945 11,317,027 604,369 0.390 0.242
Sports Direct 24,616,622 10,641,609 557,640 0.432 0.205
Kohl’s 13,512,453 5,182,260 287,375 0.384 0.112
Walmart 10,506,085 3,902,749 206,225 0.371 0.087
Amazon 10,096,987 3,984,432 197,990 0.395 0.084
# 1. Creamos la etiqueta flotante para cada distribuidor
r_dist_interactivo <- r_dist %>%
  mutate(
    etiqueta = paste0(
      "<b>Distribuidor:</b> ", distribuidor, "<br>",
      "<b>Ventas totales:</b> ", dollar(ventas), "<br>",
      "<b>Margen operativo:</b> ", percent(margen, accuracy = 0.1)
    )
  )

# 2. Construimos el gráfico conservando tus etiquetas de texto y colores
grafico_dist <- ggplot(r_dist_interactivo, aes(x = reorder(distribuidor, ventas), y = ventas, text = etiqueta)) +
  geom_col(aes(fill = margen)) +
  geom_text(aes(label = percent(margen, accuracy = 0.1)), hjust = -0.1) +
  coord_flip() +
  scale_y_continuous(labels = label_dollar(scale = 1e-6, suffix = "M"),
                     expand = expansion(mult = c(0, 0.15))) +
  scale_fill_gradient(low = "#9ecae1", high = "#08519c", labels = percent) +
  labs(title = "Ventas por distribuidor (etiqueta = margen operativo)",
       x = NULL, y = "Ventas (millones USD)", fill = "Margen")

# 3. Convertimos a interactivo
ggplotly(grafico_dist, tooltip = "text")

5. Desempeño por Región y Estado

r_reg <- resumen_por(datos, region)
kable(r_reg, digits = 3, format.args = list(big.mark = ","))
region ventas utilidad unidades margen part_ventas
West 36,436,157 13,017,584 686,985 0.357 0.303
Northeast 25,078,267 9,732,774 501,279 0.388 0.209
Southeast 21,374,436 8,393,059 407,000 0.393 0.178
South 20,603,356 9,221,605 492,260 0.448 0.171
Midwest 16,674,434 6,859,945 391,337 0.411 0.139
# 1. Creamos la etiqueta flotante únicamente con ventas y porcentaje de margen
r_reg_interactivo <- r_reg %>%
  mutate(
    etiqueta = paste0(
      "<b>Ventas:</b> ", dollar(ventas), "<br>",
      "<b>Margen:</b> ", percent(margen, accuracy = 0.1)
    )
  )

# 2. Construimos el gráfico sin el eje secundario innecesario
grafico_reg <- ggplot(r_reg_interactivo, aes(x = reorder(region, ventas))) +
  geom_col(aes(y = ventas, text = etiqueta), fill = "#2c7fb8") +
  geom_point(aes(y = margen * max(ventas) / 0.5, text = etiqueta), color = "red", size = 4) +
  scale_y_continuous(labels = label_dollar(scale = 1e-6, suffix = "M")) +
  coord_flip() +
  labs(title = "Ventas y margen por región", x = NULL, y = "Ventas (millones USD)")

# 3. Convertimos a interactivo y centramos el título
ggplotly(grafico_reg, tooltip = "text") %>%
  layout(title = list(text = "Ventas y margen por región", x = 0.5, xanchor = "center"))
# 1. Preparamos los datos y creamos el texto personalizado para el cursor
mapa_datos <- datos %>%
  group_by(estado) %>%
  summarise(ventas = sum(ventas_total, na.rm = TRUE), .groups = "drop") %>%
  mutate(
    state = as.character(estado),
    etiqueta = paste0(
      "<b>Estado:</b> ", state, "<br>",
      "<b>Ventas totales:</b> ", dollar(ventas)
    )
  )

# 2. Creamos el mapa base asignando la etiqueta al parámetro 'text'
mapa_base <- plot_usmap(data = mapa_datos, values = "ventas", color = "white", linewidth = 0.3) +
  aes(text = etiqueta) +
  scale_fill_continuous(
    low = "#deebf7",      # Azul claro para menos ventas
    high = "#08306b",     # Azul oscuro para mayores ventas
    name = "Ventas totales",
    labels = label_dollar(scale = 1e-6, suffix = "M")
  ) +
  labs(title = "Distribución geográfica de ventas en Estados Unidos") +
  theme(
    legend.position = "right",
    plot.title = element_text(face = "bold", size = 14)
  )

# 3. Convertimos el gráfico a interactivo indicando que muestre solo 'text'
ggplotly(mapa_base, tooltip = "text")
r_est <- resumen_por(datos, estado)

# Top 10 estados por ventas (versión interactiva)
grafico_top10 <- r_est %>% 
  slice_head(n = 10) %>%
  mutate(
    etiqueta = paste0(
      "<b>Estado:</b> ", estado, "<br>",
      "<b>Ventas totales:</b> ", dollar(ventas), "<br>",
      "<b>Margen:</b> ", percent(margen, accuracy = 0.1)
    )
  ) %>%
  ggplot(aes(x = reorder(estado, ventas), y = ventas, fill = margen, text = etiqueta)) +
  geom_col() +
  coord_flip() +
  scale_y_continuous(labels = label_dollar(scale = 1e-6, suffix = "M")) +
  scale_fill_gradient(low = "#fee0d2", high = "#de2d26", labels = percent) +
  labs(title = "Top 10 estados por ventas", x = NULL,
       y = "Ventas (millones USD)", fill = "Margen")

ggplotly(grafico_top10, tooltip = "text")
# Estados con mayor margen (con ventas relevantes)
r_est %>% filter(ventas > median(ventas)) %>% arrange(desc(margen)) %>%
  slice_head(n = 5) %>% kable(digits = 3, format.args = list(big.mark = ","))
estado ventas utilidad unidades margen part_ventas
Alabama 2,513,424 1,368,206.4 63,327 0.544 0.021
Tennessee 2,567,190 1,269,585.1 66,077 0.495 0.021
Michigan 2,287,283 1,050,351.5 50,095 0.459 0.019
Idaho 2,742,753 1,222,558.9 63,827 0.446 0.023
Mississippi 2,218,609 959,892.2 56,814 0.433 0.018

6. Desempeño por Producto

r_prod <- resumen_por(datos, producto) %>%
  mutate(
    etiqueta = paste0(
      "<b>Producto:</b> ", producto, "<br>",
      "<b>Ventas:</b> ", dollar(ventas), "<br>",
      "<b>Margen:</b> ", percent(margen, accuracy = 0.1), "<br>",
      "<b>Unidades:</b> ", comma(unidades)
    )
  )

g_prod <- ggplot(r_prod, aes(x = ventas, y = margen, size = unidades, text = etiqueta)) +
  geom_point(color = "#08519c", alpha = 0.8) +
  geom_text(aes(label = producto), vjust = -1.2, size = 3.5, check_overlap = TRUE) +
  scale_x_continuous(labels = label_dollar(scale = 1e-6, suffix = "M"),
                     expand = expansion(mult = 0.18)) + # Evita cortes a los lados
  scale_y_continuous(labels = percent_format(accuracy = 1),
                     expand = expansion(mult = 0.15)) + # Evita cortes arriba y abajo
  scale_size_continuous(range = c(4, 15), labels = comma) + # Agranda puntos pequeños y quita '4e+05'
  labs(
    title = "Portafolio de Productos: Ventas vs. Margen Operativo",
    x = "Ventas (millones USD)",
    y = "Margen operativo",
    size = "Unidades"
  ) +
  theme_minimal()

ggplotly(g_prod, tooltip = "text")

7. Desempeño por Método de Venta

r_met <- resumen_por(datos, metodo_venta)
kable(r_met, digits = 3, format.args = list(big.mark = ","))
metodo_venta ventas utilidad unidades margen part_ventas
Online 44,965,657 19,552,538 939,093 0.435 0.374
Outlet 39,536,618 14,913,301 849,778 0.377 0.329
In-store 35,664,375 12,759,129 689,990 0.358 0.297
ggplot(r_met, aes(x = "", y = ventas, fill = metodo_venta)) +
  geom_col(width = 1) +
  coord_polar("y") +
  geom_text(aes(label = percent(part_ventas, accuracy = 0.1)),
            position = position_stack(vjust = 0.5), color = "white") +
  theme_void() +
  labs(title = "Participación en ventas por método de venta", fill = NULL)

8. Cruces Estratégicos

8.1 Distribuidor x Método de Venta (margen)

datos %>%
  group_by(distribuidor, metodo_venta) %>%
  summarise(margen = sum(utilidad_operativa) / sum(ventas_total), .groups = "drop") %>%
  ggplot(aes(x = metodo_venta, y = distribuidor, fill = margen)) +
  geom_tile(color = "white") +
  geom_text(aes(label = percent(margen, accuracy = 0.1))) +
  scale_fill_gradient(low = "#fff7bc", high = "#d95f0e", labels = percent) +
  labs(title = "Margen operativo: distribuidor x método de venta",
       x = NULL, y = NULL, fill = "Margen")

8.2 Región x Producto (ventas)

# 1. Agrupamos los datos y creamos la etiqueta únicamente con las ventas
datos_cruce2 <- datos %>%
  group_by(region, producto) %>%
  summarise(ventas = sum(ventas_total, na.rm = TRUE), .groups = "drop") %>%
  mutate(
    etiqueta = paste0("<b>Ventas:</b> ", dollar(ventas))
  )

# 2. Construimos el gráfico agrupado conectando la etiqueta
grafico_cruce2 <- ggplot(datos_cruce2, aes(x = region, y = ventas, fill = producto, text = etiqueta)) +
  geom_col(position = "dodge") +
  scale_y_continuous(labels = label_dollar(scale = 1e-6, suffix = "M")) +
  labs(title = "Ventas por región y producto", x = NULL,
       y = "Ventas (millones USD)", fill = "Producto")

# 3. Convertimos a interactivo
ggplotly(grafico_cruce2, tooltip = "text")

9. Relaciones entre variables numéricas

# 1. Creamos el boxplot comparando el margen operativo por método de venta
grafico_box <- ggplot(datos, aes(x = metodo_venta, y = margen_operativo, fill = metodo_venta)) +
  geom_boxplot(alpha = 0.85, outlier.color = "#de2d26", outlier.alpha = 0.6) +
  scale_y_continuous(labels = percent_format(accuracy = 1)) +
  scale_fill_manual(values = c("#08519c", "#3182bd", "#6baed6")) +
  labs(
    title = "Distribución del margen operativo por método de venta",
    x = NULL,
    y = "Margen operativo"
  ) +
  theme_minimal() +
  theme(
    legend.position = "none",
    plot.title = element_text(face = "bold", size = 14)
  )

# 2. Lo convertimos a interactivo (Plotly calcula automáticamente mediana y cuartiles)
ggplotly(grafico_box)

```

10. Conclusiones y Recomendaciones para la Junta Directiva

Resumen Ejecutivo: El negocio de Adidas en Estados Unidos muestra una sólida generación de ingresos liderada por mercados clave y categorías urbanas, pero presenta una oportunidad inmediata de maximizar la utilidad neta migrando volumen hacia el canal digital y ajustando la política de descuentos en segmentos de alta rotación.

1. ¿Dónde se Concentra el Negocio?

  • Mercados y regiones líderes: La facturación principal se concentra en las regiones del Oeste (West) y Noreste (Northeast), apalancada por estados de alta densidad comercial como Nueva York, California, Florida y Texas.

2. Las ventas están concentradas en pocos distribuidores.

West Gear (27,0 %), Foot Locker (24,2 %) y **Sports Direct* (20,5 %) suman cerca del 72 % de las ventas. underline(Sports Direct) es el distribuidor más eficiente, con un margen de 43,2 % frente al 37,6 % de West Gear, que es el que más vende. Walmart y Amazon aportan cada uno cerca del 8 % de las ventas.

3. ¿Dónde está la Rentabilidad?

3.1. El canal online es el más valioso.

Genera el 37 % de las ventas y el 41 % de la utilidad, con un margen de 43,5 %.Convirtiendolo en el formato más rentable de la operación, alcanzando una mediana de margen operativo del 47% (con transacciones pico de hasta el 80%) aportando utilidad limpia sin exigir grandes inventarios. Es el único método cuya participación en la utilidad es menor que su participación en ventas, junto con una brecha menor en Outlet. La tienda física (In-store) aporta el 30 % de las ventas pero solo el 27 % de la utilidad, con el margen más bajo (35,8 %). Es el único método cuya participación en la utilidad es menor que su participación en ventas, junto con una brecha menor en Outlet producto de los descuentos agresivos.

3.2. Oportunidades de Optimización y Crecimiento

Los estados grandes no son los más rentables. New York, California, Florida y Texas suman el 26 % de las ventas. California tiene un margen de 34,5 %, mientras que Texas alcanza 42,8 %. Estados pequeños como Alabama (54,4 %) y Tennessee (49,5 %) superan ampliamente el margen promedio. En el extremo opuesto están Hawái (28,5 %) y Washington (28,8 %).

La combinación importa más que cada variable por separado. - Los mejores márgenes aparecen en Sports Direct (Online 45,1 % y Outlet 44,6 %) y en West Gear Online (44,5 %). - Los peores aparecen en Walmart In-store (30,0 %) y West Gear Outlet (34,2 %). - En la región West, Women’s Apparel tiene un margen de solo 29,8 %, mientras que en South el mismo producto llega a 52,1 %.

4. Desempeño por Canal de Venta

  • Online vs. Tienda Física (In-store): Mientras las tiendas físicas enfrentan una estructura de costos rígida que limita su margen mediano al 35% (rango entre 30% y 40%), el canal Online entrega 12 puntos porcentuales adicionales de rentabilidad mediana (47%).
  • Rol del Outlet: Con una mediana del 40%, cumple su función de liquidación de inventario con rentabilidad intermedia, pero requiere control estricto sobre sus pisos mínimos de descuento.

Men’s Street Footwear es el producto estrella. Aporta el 23,0 % de las ventas y el 24,6 % de la utilidad, con un margen de 42 %. Men’s Athletic Footwear tiene el margen más bajo (36,1 %). El calzado en conjunto representa cerca del 66 % de las ventas.


5. Plan de Acción Recomendado

  1. Acelerar la inversión en comercio electrónico (Online): Redirigir presupuesto de marketing digital y lanzamientos exclusivos hacia el canal Online para capturar su margen mediano del 47% y reducir la dependencia de infraestructura física.
  2. Establecer pisos de margen en Outlet y Calzado Deportivo: Fijar un límite mínimo de rentabilidad (ej. no inferior al 25%) en promociones de Outlet y auditar los costos o descuentos de Men’s Athletic Footwear para elevar su margen del 36% hacia el promedio general (~40%).
  3. Impulsar venta cruzada (Cross-Selling) en categorías de nicho: Integrar Women’s Athletic Footwear y Men’s Apparel en campañas conjuntas con los productos estrella (Men’s Street Footwear y Women’s Apparel) para acelerar su rotación sin sacrificar precio.
  4. Transformar tiendas físicas hacia modelos híbridos: Reenfocar las tiendas In-store de alto tráfico como centros de experiencia y puntos de recogida (click & collect) para diluir costos fijos y mejorar su conversión operativa.