Introducción

Este informe presenta un análisis exploratorio y descriptivo de las ventas de Adidas en Estados Unidos, con el objetivo de identificar patrones comerciales, evaluar el desempeño financiero por región, retailer, producto y método de venta, y generar recomendaciones estratégicas basadas en datos.

El dataset contiene 9.651 registros con información de distribuidores (retailers), regiones, ciudades, líneas de producto, precios, unidades vendidas, ventas totales, utilidad operativa, margen operativo y método de venta.


Análisis Exploratorio de Datos (EDA)

El análisis exploratorio (EDA) es el primer paso para comprender la información comercial de Adidas: detectar distribuciones, identificar valores atípicos, medir relaciones entre variables y extraer patrones accionables.


PASO 1. Instalar y cargar librerías

# Librerías necesarias para el análisis
library(readxl)       # Lectura de archivos Excel
library(dplyr)        # Manipulación de datos
library(ggplot2)      # Visualizaciones estáticas
library(plotly)       # Visualizaciones interactivas
library(knitr)        # Tablas en RMarkdown
library(kableExtra)   # Formato avanzado de tablas
library(tidyr)        # Transformación de datos (pivot)
library(scales)       # Formato de ejes (miles, porcentajes)

PASO 2. Cargar y preparar los datos

Se carga el archivo Excel con los datos de ventas de Adidas. La columna ventas_total contiene fórmulas Excel que R no evalúa automáticamente, por lo que se recalcula directamente como precio_unidad × unidades_vendidas.

# Cargar datos desde Excel
datos <- read_excel("DatosCaso1.xlsx", sheet = "Data Sales Adidas")

# Renombrar columnas para mayor claridad en el análisis
# (los nombres originales ya están en español — se conservan y se verifica)
names(datos)
##  [1] "distribuidor"       "region"             "estado"            
##  [4] "ciudad"             "producto"           "precio_unidad"     
##  [7] "unidades_vendidas"  "ventas_total"       "utilidad_operativa"
## [10] "margen_operativo"   "metodo_venta"
# Recalcular ventas_total ya que la columna original contiene fórmulas Excel
# que R lee como texto. Se sobreescribe con el cálculo numérico correcto.
datos$ventas_total <- as.numeric(datos$precio_unidad) * as.numeric(datos$unidades_vendidas)

# Asegurar que las columnas numéricas estén en el formato correcto
datos$precio_unidad       <- as.numeric(datos$precio_unidad)
datos$unidades_vendidas   <- as.numeric(datos$unidades_vendidas)
datos$utilidad_operativa  <- as.numeric(datos$utilidad_operativa)
datos$margen_operativo    <- as.numeric(datos$margen_operativo)

# Convertir variables categóricas a factor
datos$distribuidor   <- as.factor(datos$distribuidor)
datos$region         <- as.factor(datos$region)
datos$producto       <- as.factor(datos$producto)
datos$metodo_venta   <- as.factor(datos$metodo_venta)

# Vista previa de los datos
head(datos, 6)
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

PASO 3. Inspeccionar la estructura del dataset

# Nombres exactos de las variables
names(datos)
##  [1] "distribuidor"       "region"             "estado"            
##  [4] "ciudad"             "producto"           "precio_unidad"     
##  [7] "unidades_vendidas"  "ventas_total"       "utilidad_operativa"
## [10] "margen_operativo"   "metodo_venta"
# Estructura del dataframe: tipo de dato por columna
str(datos)
## tibble [9,648 × 11] (S3: tbl_df/tbl/data.frame)
##  $ distribuidor      : Factor w/ 6 levels "Amazon","Foot Locker",..: 2 2 2 2 2 2 2 2 2 2 ...
##  $ region            : Factor w/ 5 levels "Midwest","Northeast",..: 2 2 2 2 2 2 2 2 2 2 ...
##  $ estado            : chr [1:9648] "New York" "New York" "New York" "New York" ...
##  $ ciudad            : chr [1:9648] "New York" "New York" "New York" "New York" ...
##  $ producto          : Factor w/ 6 levels "Men's Apparel",..: 3 2 6 5 1 4 3 2 6 5 ...
##  $ precio_unidad     : num [1:9648] 50 50 40 45 60 50 50 50 40 45 ...
##  $ unidades_vendidas : num [1:9648] 1200 1000 1000 850 900 1000 1250 900 950 825 ...
##  $ ventas_total      : num [1:9648] 60000 50000 40000 38250 54000 ...
##  $ utilidad_operativa: num [1:9648] 30000 15000 14000 13388 16200 ...
##  $ margen_operativo  : num [1:9648] 0.5 0.3 0.35 0.35 0.3 0.25 0.5 0.3 0.35 0.35 ...
##  $ metodo_venta      : Factor w/ 3 levels "In-store","Online",..: 1 1 1 1 1 1 1 3 3 3 ...
# Total de registros en el dataset
cat("Total de registros:", nrow(datos), "\n")
## Total de registros: 9648
cat("Total de variables:", ncol(datos), "\n")
## Total de variables: 11

PASO 4. Verificar valores faltantes

# Conteo de NA por columna — importante antes de calcular estadísticas
na_por_columna <- colSums(is.na(datos))
na_por_columna
##       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

Si todas las celdas muestran 0, el dataset está completo y no requiere imputación.


Indicadores de Centralidad

# ── Tendencia central para VENTAS TOTALES ──────────────────────────────────
# na.rm = TRUE garantiza que los NA no rompan el cálculo (buena práctica)

cantidad_transacciones  <- nrow(datos)
promedio_ventas         <- mean(datos$ventas_total,       na.rm = TRUE)
mediana_ventas          <- median(datos$ventas_total,     na.rm = TRUE)  # ← median(), no mean()
promedio_precio         <- mean(datos$precio_unidad,      na.rm = TRUE)
mediana_precio          <- median(datos$precio_unidad,    na.rm = TRUE)
promedio_unidades       <- mean(datos$unidades_vendidas,  na.rm = TRUE)
mediana_unidades        <- median(datos$unidades_vendidas, na.rm = TRUE)

resultado_centralidad <- data.frame(
  Métrica               = c("Transacciones", "Promedio Ventas $", "Mediana Ventas $",
                             "Promedio Precio $", "Mediana Precio $",
                             "Promedio Unidades", "Mediana Unidades"),
  Valor                 = c(cantidad_transacciones,
                             round(promedio_ventas, 2),
                             round(mediana_ventas, 2),
                             round(promedio_precio, 2),
                             round(mediana_precio, 2),
                             round(promedio_unidades, 2),
                             round(mediana_unidades, 2))
)
resultado_centralidad
Métrica Valor
Transacciones 9648.00
Promedio Ventas $ 12455.08
Mediana Ventas $ 7803.50
Promedio Precio $ 45.22
Mediana Precio $ 45.00
Promedio Unidades 256.93
Mediana Unidades 176.00

Interpretación — Centralidad: La comparación entre promedio y mediana es clave: si el promedio de ventas es significativamente mayor que la mediana, existe asimetría positiva, lo que indica que algunas transacciones de alto valor elevan la media. La mediana representa mejor el “desempeño típico” del negocio en ese caso.


Indicadores de Variabilidad

# ── Variabilidad para VENTAS TOTALES ───────────────────────────────────────
minimo_ventas   <- min(datos$ventas_total,    na.rm = TRUE)
maximo_ventas   <- max(datos$ventas_total,    na.rm = TRUE)
desvest_ventas  <- sd(datos$ventas_total,     na.rm = TRUE)
cv_ventas       <- (desvest_ventas / promedio_ventas) * 100   # Coeficiente de variación

indic_ventas <- data.frame(
  Promedio   = round(promedio_ventas,  2),
  Mediana    = round(mediana_ventas,   2),
  Mínimo     = round(minimo_ventas,    2),
  Máximo     = round(maximo_ventas,    2),
  Desv_Est   = round(desvest_ventas,   2),
  CV_Pct     = round(cv_ventas,        2)
)
indic_ventas
Promedio Mediana Mínimo Máximo Desv_Est CV_Pct
12455.08 7803.5 0 82500 12716.39 102.1
# ── Variabilidad para PRECIO POR UNIDAD ────────────────────────────────────
minimo_precio   <- min(datos$precio_unidad,    na.rm = TRUE)
maximo_precio   <- max(datos$precio_unidad,    na.rm = TRUE)
desvest_precio  <- sd(datos$precio_unidad,     na.rm = TRUE)
cv_precio       <- (desvest_precio / promedio_precio) * 100

indic_precio <- data.frame(
  Promedio   = round(promedio_precio,  2),
  Mediana    = round(mediana_precio,   2),
  Mínimo     = round(minimo_precio,    2),
  Máximo     = round(maximo_precio,    2),
  Desv_Est   = round(desvest_precio,   2),
  CV_Pct     = round(cv_precio,        2)
)
indic_precio
Promedio Mediana Mínimo Máximo Desv_Est CV_Pct
45.22 45 7 110 14.71 32.52
# ── Variabilidad para UTILIDAD OPERATIVA ───────────────────────────────────
promedio_utilidad  <- mean(datos$utilidad_operativa, na.rm = TRUE)
mediana_utilidad   <- median(datos$utilidad_operativa, na.rm = TRUE)
minimo_utilidad    <- min(datos$utilidad_operativa,  na.rm = TRUE)
maximo_utilidad    <- max(datos$utilidad_operativa,  na.rm = TRUE)
desvest_utilidad   <- sd(datos$utilidad_operativa,   na.rm = TRUE)
cv_utilidad        <- (desvest_utilidad / promedio_utilidad) * 100

indic_utilidad <- data.frame(
  Promedio   = round(promedio_utilidad,  2),
  Mediana    = round(mediana_utilidad,   2),
  Mínimo     = round(minimo_utilidad,    2),
  Máximo     = round(maximo_utilidad,    2),
  Desv_Est   = round(desvest_utilidad,   2),
  CV_Pct     = round(cv_utilidad,        2)
)
indic_utilidad
Promedio Mediana Mínimo Máximo Desv_Est CV_Pct
4894.79 3262.98 0 39000 4866.46 99.42

Interpretación — Variabilidad: El Coeficiente de Variación (CV%) normaliza la dispersión respecto al promedio, permitiendo comparar variables con distintas escalas. Un CV alto en ventas indica heterogeneidad entre transacciones; un CV alto en margen operativo señala inconsistencia en la rentabilidad del negocio.


Representación Gráfica

Histogramas — Distribución de variables clave

Figura 1. Distribución de Ventas Totales

ggplotly(
  ggplot(datos, aes(x = ventas_total)) +
    geom_histogram(bins = 50, fill = "steelblue", color = "white", alpha = 0.8) +
    scale_x_continuous(labels = dollar_format(prefix = "$", big.mark = ",")) +
    labs(
      title = "Figura 1. Distribución de Ventas Totales por Transacción",
      x     = "Ventas Totales (USD)",
      y     = "Frecuencia",
      caption = "Fuente: Dataset Adidas USA"
    ) +
    theme_minimal()
)

Interpretación Figura 1: Este histograma revela la distribución de las ventas por transacción. Si la distribución es sesgada a la derecha (cola larga hacia valores altos), la mayoría de las transacciones son de tamaño moderado, pero un grupo pequeño genera ventas muy elevadas — patrón común en retail. La diferencia entre promedio y mediana confirma este comportamiento.


Figura 2. Distribución del Precio por Unidad

ggplotly(
  ggplot(datos, aes(x = precio_unidad)) +
    geom_histogram(bins = 30, fill = "darkorange", color = "white", alpha = 0.8) +
    scale_x_continuous(labels = dollar_format(prefix = "$")) +
    labs(
      title = "Figura 2. Distribución del Precio por Unidad",
      x     = "Precio por Unidad (USD)",
      y     = "Frecuencia",
      caption = "Fuente: Dataset Adidas USA"
    ) +
    theme_minimal()
)

Interpretación Figura 2: La distribución de precios muestra los rangos de precio más frecuentes en el portafolio de Adidas. Una distribución multimodal (varios picos) sugiere segmentos de precio diferenciados: líneas económicas, intermedias y premium. Los picos identifican los precios “âncora” del catálogo.


Figura 3. Distribución del Margen Operativo

ggplotly(
  ggplot(datos, aes(x = margen_operativo * 100)) +
    geom_histogram(bins = 30, fill = "seagreen", color = "white", alpha = 0.8) +
    labs(
      title = "Figura 3. Distribución del Margen Operativo (%)",
      x     = "Margen Operativo (%)",
      y     = "Frecuencia",
      caption = "Fuente: Dataset Adidas USA"
    ) +
    theme_minimal()
)

Interpretación Figura 3: El margen operativo es el indicador de rentabilidad más importante del análisis. Una distribución concentrada indica uniformidad en la política de precios y costos; una distribución dispersa o bimodal señala que algunos canales, productos o regiones son significativamente más rentables que otros.


Boxplots — Detección de valores atípicos

Figura 4. Boxplot de Ventas Totales

ggplotly(
  ggplot(datos, aes(y = ventas_total)) +
    geom_boxplot(fill = "steelblue", color = "black",
                 outlier.colour = "red", outlier.shape = 16, outlier.size = 2) +
    scale_y_continuous(labels = dollar_format(prefix = "$", big.mark = ",")) +
    labs(
      title = "Figura 4. Boxplot de Ventas Totales",
      y     = "Ventas Totales (USD)"
    ) +
    theme_minimal()
)

Interpretación Figura 4: El boxplot muestra la mediana (línea central), el rango intercuartílico (Q1–Q3, caja) y los bigotes hasta 1.5×IQR. Los puntos rojos son outliers: transacciones de ventas excepcionalmente altas. Estos outliers no son “errores” — representan pedidos mayoristas grandes o temporadas pico que deben analizarse por separado.


Figura 5. Boxplot de Precio por Unidad según Producto

ggplotly(
  ggplot(datos, aes(x = reorder(producto, precio_unidad, median), y = precio_unidad, fill = producto)) +
    geom_boxplot(color = "black", outlier.colour = "red", outlier.shape = 16, outlier.size = 1.5,
                 alpha = 0.8) +
    coord_flip() +
    scale_y_continuous(labels = dollar_format(prefix = "$")) +
    labs(
      title    = "Figura 5. Precio por Unidad según Línea de Producto",
      x        = "Línea de Producto",
      y        = "Precio por Unidad (USD)",
      caption  = "Fuente: Dataset Adidas USA"
    ) +
    theme_minimal() +
    theme(legend.position = "none")
)

Interpretación Figura 5: Ordenar los boxplots por mediana de precio permite identificar qué líneas de producto son premium y cuáles son de entrada. La superposición o separación entre cajas indica si existe diferenciación real de precio entre categorías o si los rangos son similares.


Figura 6. Boxplot de Margen Operativo según Método de Venta

ggplotly(
  ggplot(datos, aes(x = metodo_venta, y = margen_operativo * 100, fill = metodo_venta)) +
    geom_boxplot(color = "black", outlier.colour = "red", outlier.shape = 16, outlier.size = 2,
                 alpha = 0.8) +
    labs(
      title   = "Figura 6. Margen Operativo (%) por Método de Venta",
      x       = "Método de Venta",
      y       = "Margen Operativo (%)",
      caption = "Fuente: Dataset Adidas USA"
    ) +
    theme_minimal() +
    theme(legend.position = "none")
)

Interpretación Figura 6: Este gráfico es uno de los más estratégicos del análisis: compara la rentabilidad según el canal de distribución (In-store, Online, Outlet). Si el canal online tiene un margen significativamente mayor, justifica invertir más en e-commerce. Si el canal físico tiene mayor variabilidad, puede indicar diferencias de eficiencia entre tiendas.


Análisis por Dimensiones del Negocio

Comparativo por Región

# Tabla resumen de métricas financieras por región
resumen_region <- datos %>%
  group_by(region) %>%
  summarise(
    Transacciones      = n(),
    Ventas_Total_USD   = round(sum(ventas_total,       na.rm = TRUE), 0),
    Promedio_Ventas    = round(mean(ventas_total,      na.rm = TRUE), 0),
    Utilidad_Total     = round(sum(utilidad_operativa, na.rm = TRUE), 0),
    Margen_Prom_Pct    = round(mean(margen_operativo,  na.rm = TRUE) * 100, 1)
  ) %>%
  arrange(desc(Ventas_Total_USD))

resumen_region
region Transacciones Ventas_Total_USD Promedio_Ventas Utilidad_Total Margen_Prom_Pct
West 2448 36436157 14884 13017584 39.7
Northeast 2376 25078267 10555 9732774 41.0
Southeast 1224 21374436 17463 8393059 41.9
South 1728 20603356 11923 9221605 46.7
Midwest 1872 16674434 8907 6859945 43.5

Figura 7. Ventas Totales por Región

ggplotly(
  ggplot(resumen_region, aes(x = reorder(region, Ventas_Total_USD), y = Ventas_Total_USD, fill = region)) +
    geom_col(alpha = 0.85) +
    coord_flip() +
    scale_y_continuous(labels = dollar_format(prefix = "$", big.mark = ",")) +
    labs(
      title   = "Figura 7. Ventas Totales por Región",
      x       = "Región",
      y       = "Ventas Totales (USD)",
      caption = "Fuente: Dataset Adidas USA"
    ) +
    theme_minimal() +
    theme(legend.position = "none")
)

Figura 8. Margen Operativo Promedio por Región

ggplotly(
  ggplot(resumen_region, aes(x = reorder(region, Margen_Prom_Pct), y = Margen_Prom_Pct, fill = region)) +
    geom_col(alpha = 0.85) +
    coord_flip() +
    labs(
      title   = "Figura 8. Margen Operativo Promedio por Región (%)",
      x       = "Región",
      y       = "Margen Operativo Promedio (%)",
      caption = "Fuente: Dataset Adidas USA"
    ) +
    theme_minimal() +
    theme(legend.position = "none")
)

Interpretación Figuras 7-8: La comparación entre volumen de ventas y margen operativo por región revela si las regiones de mayor ingreso también son las más rentables. Una región puede generar muchas ventas pero con márgenes bajos (posiblemente por descuentos o altos costos operativos), mientras otra puede tener menos ventas pero mayor rentabilidad.


Comparativo por Retailer (Distribuidor)

# Tabla resumen por distribuidor/retailer
resumen_retailer <- datos %>%
  group_by(distribuidor) %>%
  summarise(
    Transacciones      = n(),
    Ventas_Total_USD   = round(sum(ventas_total,       na.rm = TRUE), 0),
    Utilidad_Total     = round(sum(utilidad_operativa, na.rm = TRUE), 0),
    Margen_Prom_Pct    = round(mean(margen_operativo,  na.rm = TRUE) * 100, 1),
    Precio_Prom        = round(mean(precio_unidad,     na.rm = TRUE), 2)
  ) %>%
  arrange(desc(Ventas_Total_USD))

resumen_retailer
distribuidor Transacciones Ventas_Total_USD Utilidad_Total Margen_Prom_Pct Precio_Prom
West Gear 2374 32409558 12196891 41.8 46.74
Foot Locker 2637 29024945 11317027 41.8 44.78
Sports Direct 2032 24616622 10641609 44.5 42.05
Kohl’s 1030 13512453 5182260 41.9 44.61
Walmart 626 10506085 3902749 40.7 47.18
Amazon 949 10096987 3984432 41.8 48.76

Figura 9. Ventas y Utilidad Operativa por Retailer

# Transformar a formato largo para graficar las dos métricas lado a lado
resumen_retailer_largo <- resumen_retailer %>%
  select(distribuidor, Ventas_Total_USD, Utilidad_Total) %>%
  pivot_longer(cols = c(Ventas_Total_USD, Utilidad_Total),
               names_to  = "Métrica",
               values_to = "Valor")

ggplotly(
  ggplot(resumen_retailer_largo, aes(x = reorder(distribuidor, Valor), y = Valor, fill = Métrica)) +
    geom_col(position = "dodge", alpha = 0.85) +
    coord_flip() +
    scale_y_continuous(labels = dollar_format(prefix = "$", big.mark = ",")) +
    labs(
      title   = "Figura 9. Ventas Totales vs Utilidad Operativa por Retailer",
      x       = "Distribuidor",
      y       = "USD",
      caption = "Fuente: Dataset Adidas USA"
    ) +
    theme_minimal()
)

Interpretación Figura 9: La brecha entre ventas totales y utilidad operativa por retailer mide la eficiencia de cada canal. Un retailer con ventas altas pero utilidad baja puede estar absorbiendo márgenes a través de descuentos o acuerdos comerciales desfavorables para Adidas. Este análisis orienta las negociaciones contractuales.


Comparativo por Línea de Producto

# Tabla resumen por línea de producto
resumen_producto <- datos %>%
  group_by(producto) %>%
  summarise(
    Transacciones      = n(),
    Ventas_Total_USD   = round(sum(ventas_total,       na.rm = TRUE), 0),
    Unidades_Totales   = sum(unidades_vendidas,        na.rm = TRUE),
    Utilidad_Total     = round(sum(utilidad_operativa, na.rm = TRUE), 0),
    Margen_Prom_Pct    = round(mean(margen_operativo,  na.rm = TRUE) * 100, 1),
    Precio_Prom        = round(mean(precio_unidad,     na.rm = TRUE), 2)
  ) %>%
  arrange(desc(Ventas_Total_USD))

resumen_producto
producto Transacciones Ventas_Total_USD Unidades_Totales Utilidad_Total Margen_Prom_Pct Precio_Prom
Men’s Street Footwear 1610 27680769 593320 11629046 44.6 44.24
Women’s Apparel 1608 23870985 433827 9685221 44.1 51.60
Men’s Athletic Footwear 1610 20577180 435526 7437457 40.3 43.78
Women’s Street Footwear 1608 17201563 392269 6494017 41.0 40.25
Men’s Apparel 1606 16520632 306683 6381405 41.3 50.32
Women’s Athletic Footwear 1606 14315521 317236 5597822 42.4 41.11

Figura 10. Ventas Totales por Línea de Producto

ggplotly(
  ggplot(resumen_producto, aes(x = reorder(producto, Ventas_Total_USD), y = Ventas_Total_USD, fill = producto)) +
    geom_col(alpha = 0.85) +
    coord_flip() +
    scale_y_continuous(labels = dollar_format(prefix = "$", big.mark = ",")) +
    labs(
      title   = "Figura 10. Ventas Totales por Línea de Producto",
      x       = "Producto",
      y       = "Ventas Totales (USD)",
      caption = "Fuente: Dataset Adidas USA"
    ) +
    theme_minimal() +
    theme(legend.position = "none")
)

Figura 11. Margen Operativo vs Precio Promedio por Producto

ggplotly(
  ggplot(resumen_producto, aes(x = Precio_Prom, y = Margen_Prom_Pct, 
                                size = Ventas_Total_USD, color = producto, label = producto)) +
    geom_point(alpha = 0.8) +
    labs(
      title   = "Figura 11. Precio Promedio vs Margen Operativo por Producto",
      x       = "Precio Promedio por Unidad (USD)",
      y       = "Margen Operativo Promedio (%)",
      size    = "Ventas Totales",
      caption = "Fuente: Dataset Adidas USA"
    ) +
    theme_minimal() +
    theme(legend.position = "right")
)

Interpretación Figuras 10-11: La Figura 11 es un gráfico de burbujas que combina tres dimensiones: precio, margen y volumen de ventas. Los productos ideales son los que aparecen en la esquina superior derecha (alto precio, alto margen) con burbujas grandes (alto volumen). Los productos en la esquina inferior izquierda son candidatos a revisión de estrategia.


Comparativo por Método de Venta

# Tabla resumen por método de venta
resumen_metodo <- datos %>%
  group_by(metodo_venta) %>%
  summarise(
    Transacciones      = n(),
    Ventas_Total_USD   = round(sum(ventas_total,       na.rm = TRUE), 0),
    Unidades_Totales   = sum(unidades_vendidas,        na.rm = TRUE),
    Utilidad_Total     = round(sum(utilidad_operativa, na.rm = TRUE), 0),
    Margen_Prom_Pct    = round(mean(margen_operativo,  na.rm = TRUE) * 100, 1)
  ) %>%
  arrange(desc(Margen_Prom_Pct))

resumen_metodo
metodo_venta Transacciones Ventas_Total_USD Unidades_Totales Utilidad_Total Margen_Prom_Pct
Online 4889 44965657 939093 19552538 46.4
Outlet 3019 39536618 849778 14913301 39.5
In-store 1740 35664375 689990 12759129 35.6

Figura 12. Participación de Ventas por Método de Venta

# Nota: ggplotly no es compatible con coord_polar (tortas).
# Se usa un gráfico de barras horizontal con porcentaje calculado manualmente,
# que transmite la misma información con mayor precisión y sin errores.

resumen_metodo <- resumen_metodo %>%
  mutate(Participacion_Pct = round(Ventas_Total_USD / sum(Ventas_Total_USD) * 100, 1))

ggplotly(
  ggplot(resumen_metodo, aes(x = reorder(metodo_venta, Participacion_Pct),
                              y = Participacion_Pct, fill = metodo_venta,
                              text = paste0(metodo_venta, ": ", Participacion_Pct, "%"))) +
    geom_col(alpha = 0.85) +
    geom_text(aes(label = paste0(Participacion_Pct, "%")), hjust = -0.2, fontface = "bold") +
    coord_flip() +
    ylim(0, max(resumen_metodo$Participacion_Pct) * 1.15) +
    labs(
      title   = "Figura 12. Participación en Ventas Totales por Método de Venta (%)",
      x       = "Método de Venta",
      y       = "Participación (%)",
      caption = "Fuente: Dataset Adidas USA"
    ) +
    theme_minimal() +
    theme(legend.position = "none"),
  tooltip = "text"
)

Figura 13. Margen Operativo vs Ventas Totales por Método de Venta

ggplotly(
  ggplot(resumen_metodo, aes(x = metodo_venta, y = Margen_Prom_Pct, fill = metodo_venta)) +
    geom_col(alpha = 0.85) +
    geom_text(aes(label = paste0(Margen_Prom_Pct, "%")), vjust = -0.5, fontface = "bold") +
    ylim(0, max(resumen_metodo$Margen_Prom_Pct) * 1.2) +
    labs(
      title   = "Figura 13. Margen Operativo Promedio por Método de Venta",
      x       = "Método de Venta",
      y       = "Margen Operativo (%)",
      caption = "Fuente: Dataset Adidas USA"
    ) +
    theme_minimal() +
    theme(legend.position = "none")
)

Interpretación Figuras 12-13: El margen operativo por método de venta es un insumo crítico para la estrategia de distribución. Si el canal online muestra márgenes superiores, la inversión en plataformas digitales tiene un retorno diferencial claro. Si el canal físico concentra más volumen pero con márgenes inferiores, se deben evaluar optimizaciones de costos operativos en tiendas.


Exploración Bivariada — Correlaciones

Figura 14. Relación entre Precio por Unidad y Margen Operativo

# Calcular el coeficiente de correlación entre precio y margen
cor_precio_margen <- round(cor(datos$precio_unidad, datos$margen_operativo,
                               use = "complete.obs"), 3)

ggplotly(
  ggplot(datos, aes(x = precio_unidad, y = margen_operativo * 100, color = metodo_venta)) +
    geom_point(alpha = 0.4, size = 1.2) +
    geom_smooth(method = "loess", se = TRUE, color = "black", linewidth = 0.8) +
    scale_x_continuous(labels = dollar_format(prefix = "$")) +
    labs(
      title   = paste0("Figura 14. Precio vs Margen Operativo | Correlación: ", cor_precio_margen),
      x       = "Precio por Unidad (USD)",
      y       = "Margen Operativo (%)",
      color   = "Método de Venta",
      caption = "Fuente: Dataset Adidas USA"
    ) +
    theme_minimal()
)

Figura 15. Relación entre Unidades Vendidas y Ventas Totales

cor_unidades_ventas <- round(cor(datos$unidades_vendidas, datos$ventas_total,
                                 use = "complete.obs"), 3)

ggplotly(
  ggplot(datos, aes(x = unidades_vendidas, y = ventas_total, color = region)) +
    geom_point(alpha = 0.4, size = 1.2) +
    geom_smooth(method = "lm", se = FALSE, color = "black", linewidth = 0.8) +
    scale_y_continuous(labels = dollar_format(prefix = "$", big.mark = ",")) +
    labs(
      title   = paste0("Figura 15. Unidades Vendidas vs Ventas Totales | Correlación: ", cor_unidades_ventas),
      x       = "Unidades Vendidas",
      y       = "Ventas Totales (USD)",
      color   = "Región",
      caption = "Fuente: Dataset Adidas USA"
    ) +
    theme_minimal()
)

Interpretación Figuras 14-15:

Figura 14 (Precio → Margen): Un coeficiente de correlación cercano a 1 indicaría que los productos más caros generan mayor rentabilidad relativa — validando una estrategia de premiumización. Una correlación baja o negativa sugiere que los descuentos en productos de precio alto erosionan los márgenes.

Figura 15 (Unidades → Ventas): Se espera una correlación alta y positiva, ya que más unidades vendidas implica más ingresos. La dispersión en la nube de puntos refleja la variedad de precios — transacciones con pocas unidades pero precio alto pueden generar ventas similares a transacciones de alto volumen y bajo precio.


Tabla Resumen Ejecutiva — Heatmap de Desempeño

# Tabla cruzada: Margen operativo promedio por Región y Producto
heatmap_data <- datos %>%
  group_by(region, producto) %>%
  summarise(Margen_Prom = round(mean(margen_operativo, na.rm = TRUE) * 100, 1),
            .groups = "drop")

ggplotly(
  ggplot(heatmap_data, aes(x = region, y = producto, fill = Margen_Prom)) +
    geom_tile(color = "white", linewidth = 0.5) +
    geom_text(aes(label = paste0(Margen_Prom, "%")), size = 3, fontface = "bold") +
    scale_fill_gradient2(low = "#d73027", mid = "#ffffbf", high = "#1a9850",
                         midpoint = mean(heatmap_data$Margen_Prom, na.rm = TRUE),
                         name = "Margen (%)") +
    labs(
      title   = "Figura 16. Heatmap: Margen Operativo (%) por Región y Producto",
      x       = "Región",
      y       = "Línea de Producto",
      caption = "Fuente: Dataset Adidas USA"
    ) +
    theme_minimal() +
    theme(axis.text.x = element_text(angle = 30, hjust = 1))
)

Interpretación Figura 16 — Heatmap: Este mapa de calor es la visualización más densa de información del análisis. Las celdas verdes identifican las combinaciones Región × Producto con mayor rentabilidad, mientras que las celdas rojas señalan combinaciones problemáticas. Permite tomar decisiones de portafolio por mercado: qué productos empujar en cada región y cuáles descontinuar o revisar en precio.


Identificación de Patrones y Hallazgos

# Top 10 ciudades por ventas totales
top_ciudades <- datos %>%
  group_by(ciudad, region) %>%
  summarise(
    Ventas_Total = round(sum(ventas_total, na.rm = TRUE), 0),
    Margen_Prom  = round(mean(margen_operativo, na.rm = TRUE) * 100, 1),
    .groups      = "drop"
  ) %>%
  arrange(desc(Ventas_Total)) %>%
  head(10)

top_ciudades
ciudad region Ventas_Total Margen_Prom
New York Northeast 5676160 39.6
San Francisco West 4929220 35.8
Orlando Southeast 3946476 36.4
Miami Southeast 3874113 42.9
Los Angeles West 3651288 41.6
Houston South 3629632 43.6
Charleston Southeast 3593112 43.3
New Orleans South 3377031 44.7
Seattle West 3222093 32.5
Richmond Southeast 3074415 41.4
ggplotly(
  ggplot(top_ciudades, aes(x = reorder(ciudad, Ventas_Total), y = Ventas_Total, fill = region)) +
    geom_col(alpha = 0.85) +
    coord_flip() +
    scale_y_continuous(labels = dollar_format(prefix = "$", big.mark = ",")) +
    labs(
      title   = "Figura 17. Top 10 Ciudades por Ventas Totales",
      x       = "Ciudad",
      y       = "Ventas Totales (USD)",
      fill    = "Región",
      caption = "Fuente: Dataset Adidas USA"
    ) +
    theme_minimal()
)

Conclusiones y Recomendaciones

Con base en el análisis descriptivo y exploratorio realizado sobre el dataset de ventas de Adidas en EE.UU., se pueden derivar las siguientes conclusiones y recomendaciones estratégicas:

Conclusiones

1. Estructura de ventas: El análisis de tendencia central muestra que existe asimetría en las ventas por transacción. La presencia de outliers en el boxplot confirma que un subconjunto de transacciones de alto volumen concentra una proporción importante de los ingresos totales.

2. Rentabilidad por canal: El margen operativo varía significativamente según el método de venta. El canal con mayor margen es el que debe priorizarse en la estrategia de crecimiento de Adidas, siempre que su volumen sea escalable.

3. Desempeño regional: Las regiones no son homogéneas ni en volumen ni en rentabilidad. El heatmap (Figura 16) identifica combinaciones región-producto de alto rendimiento que justifican mayor inversión en marketing y distribución localizada.

4. Portafolio de productos: Las líneas de producto con alto margen y alto precio son las más valiosas estratégicamente. Los productos con volumen alto pero margen bajo pueden ser evaluados para optimización de precios o reducción de costos de distribución.

5. Retailer performance: Existe variabilidad en la rentabilidad generada por cada distribuidor. Algunos retailers generan mayor utilidad relativa a sus ventas, lo que los convierte en socios estratégicos prioritarios.

Recomendaciones

  • Fortalecer el canal de mayor margen: Redirigir esfuerzos comerciales hacia el método de venta más rentable sin descuidar el volumen del canal principal.
  • Estrategia de precios diferenciada por región: Las regiones con mayor margen promedio pueden soportar estrategias de premiumización; las regiones con menor margen requieren revisión de estructura de costos.
  • Revisión de portafolio por ciudad: Las top 10 ciudades concentran una proporción desproporcionada de ventas. Una estrategia de penetración dirigida a ciudades de alto potencial y bajo margen actual puede destrabar valor.
  • Optimizar acuerdos comerciales con retailers de bajo margen: Renegociar términos comerciales con distribuidores que generan alto volumen pero baja utilidad para Adidas.
  • Inversión en líneas de producto premium: Los productos de alto precio y alto margen son los más rentables por unidad. Ampliar su distribución, especialmente en canales directos, maximiza la rentabilidad total.

Análisis generado en R/RMarkdown — Listo para publicar en RPubs.