adidas

Reseña

Creada tras la primera guerra mundial cuando Adolf “Adi” Dassler empezó a fabricar calzado deportivo en el cuarto de lavado de su madre en Herzogenaurach (Alemania). En 1924, se unió a su hermano Rudolf y fundaron la Dassler Brothers Shoe Factory (Gebrüder Dassler Schuhfabrik).Tras diferencias personales, Rudolf fundó Puma en 1948 y en 1949 Adolf registró oficialmente Adidas AG (nombre derivado de “Adi Das(s)ler”) Desde su creación en 1949, Adidas incorporó las tres rayas como medio de soporte en el calzado, que luego se convertirían en su identidad visual

El objetivo de Adidas según su propia visión corporativa es:

“Ser la mejor empresa de artículos deportivos del mundo.”

Este objetivo general se complementa con una misión más concreta:

Crear productos deportivos que inspiren y permitan a todas las personas alcanzar su máximo potencial.

En términos estratégicos, la marca resume su propósito así:

  • Impulsar el deporte y la cultura deportiva en todo el mundo.

  • Fomentar la innovación en calzado, ropa y accesorios.

  • Hacer del deporte una herramienta para cambiar vidas.

“Through sport, we have the power to change lives.” (“A través del deporte, tenemos el poder de cambiar vidas”).

Introducción

Adidas es una de las marcas deportivas más reconocidas a nivel mundial. El presente análisis descriptivo evalúa el comportamiento de precios, unidades vendidas, ventas totales, utilidad operativa y margen operativo, desagregando por método de venta y producto. siguiendo los pasos descriptos por la profesora en los casos Vivienda y Colombina .

Paso 1: Cargar librerías

library(readxl)
library(dplyr)
library(ggplot2)
library(plotly)
library(knitr)
library(kableExtra)
library(tidyr)
library(stringr)

Paso 2: Importar datos y crear identificador

datos_adidas <- read_excel("Adidas.xlsx", sheet = "Data Sales Adidas",
                           col_types = c("text","text","text","text","text",
                                         "numeric","numeric","numeric",
                                         "numeric","numeric","text"))

# Agregar columna id para numerar filas
id <- 1:nrow(datos_adidas)
datos_adidas <- data.frame(id, datos_adidas)

# Estructura y primeras filas para verificar que los datos esten en el formato esperado
class(datos_adidas)  
## [1] "data.frame"
colnames(datos_adidas)  
##  [1] "id"               "retailer"         "Region"           "State"           
##  [5] "City"             "Product"          "price_per_unit"   "units_sold"      
##  [9] "total_sales"      "operating_profit" "operating_margin" "sales_method"
head(datos_adidas)
id retailer Region State City Product price_per_unit units_sold total_sales operating_profit operating_margin sales_method
1 Foot Locker Northeast New York New York Men’s Street Footwear 50 1200 60000 30000.0 0.50 In-store
2 Foot Locker Northeast New York New York Men’s Athletic Footwear 50 1000 50000 15000.0 0.30 In-store
3 Foot Locker Northeast New York New York Women’s Street Footwear 40 1000 40000 14000.0 0.35 In-store
4 Foot Locker Northeast New York New York Women’s Athletic Footwear 45 850 38250 13387.5 0.35 In-store
5 Foot Locker Northeast New York New York Men’s Apparel 60 900 54000 16200.0 0.30 In-store
6 Foot Locker Northeast New York New York Women’s Apparel 50 1000 50000 12500.0 0.25 In-store

Paso 3: Limpieza mínima, Variables derivadas y Renombramos o Creamos nombre en español

# Normalizar nombres básicos 
names(datos_adidas) <- make.names(names(datos_adidas))

#ventas totales por region
ventas_region <- datos_adidas %>%
  group_by(Region) %>%
  summarise(total_sales = sum(total_sales, na.rm = TRUE))
print(ventas_region)
## # A tibble: 5 × 2
##   Region    total_sales
##   <chr>           <dbl>
## 1 Midwest      16674434
## 2 Northeast    25078267
## 3 South        20603356
## 4 Southeast    21374436
## 5 West         36436157
# Variables auxiliares para reportar
datos_adidas <- datos_adidas %>% 
  mutate(
    margen_operativo_pct = 100 * operating_margin,   # margen en % para lectura
    metodo_venta = sales_method,
    producto = Product
  )

summary(select(datos_adidas, price_per_unit, units_sold, total_sales, operating_profit, operating_margin, margen_operativo_pct))
##  price_per_unit     units_sold      total_sales    operating_profit
##  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   
##  operating_margin margen_operativo_pct
##  Min.   :0.100    Min.   :10.0        
##  1st Qu.:0.350    1st Qu.:35.0        
##  Median :0.410    Median :41.0        
##  Mean   :0.423    Mean   :42.3        
##  3rd Qu.:0.490    3rd Qu.:49.0        
##  Max.   :0.800    Max.   :80.0

Paso 4: Indicadores de Centralidad y Dispersión

# realizamos calculos individuales de premedio y mediana
promedio_precio    <- mean(datos_adidas$price_per_unit, na.rm = TRUE)
promedio_unidades  <- mean(datos_adidas$units_sold, na.rm = TRUE)
promedio_ventas    <- mean(datos_adidas$total_sales, na.rm = TRUE)
promedio_utilidad  <- mean(datos_adidas$operating_profit, na.rm = TRUE)
promedio_margen    <- mean(datos_adidas$operating_margin, na.rm = TRUE)
mediana_margen_pct <- median(datos_adidas$margen_operativo_pct, na.rm = TRUE)

resultado_prom <- data.frame(
  promedio_precio, promedio_unidades, promedio_ventas,
  promedio_utilidad, promedio_margen, mediana_margen_pct
)

kable(resultado_prom, caption = "Indicadores de centralidad - Adidas", digits = 2)
Indicadores de centralidad - Adidas
promedio_precio promedio_unidades promedio_ventas promedio_utilidad promedio_margen mediana_margen_pct
45.22 256.93 12455.08 4894.79 0.42 41

Paso 5: Filtros y subconjuntos

# Ejemplo de filtro por canal y producto (ajustar si se desea otro subset)
datos_sub <- subset(datos_adidas, metodo_venta %in% c("In-store", "Online", "Outlet"))

# Resumen del subconjunto
kable(as.data.frame(summary(select(datos_sub, price_per_unit, units_sold, total_sales, operating_profit, operating_margin))), 
      caption = "Resumen numérico del subconjunto")
Resumen numérico del subconjunto
Var1 Var2 Freq
price_per_unit Min. : 7.00
price_per_unit 1st Qu.: 35.00
price_per_unit Median : 45.00
price_per_unit Mean : 45.22
price_per_unit 3rd Qu.: 55.00
price_per_unit Max. :110.00
units_sold Min. : 0.0
units_sold 1st Qu.: 106.0
units_sold Median : 176.0
units_sold Mean : 256.9
units_sold 3rd Qu.: 350.0
units_sold Max. :1275.0
total_sales Min. : 0
total_sales 1st Qu.: 4065
total_sales Median : 7804
total_sales Mean :12455
total_sales 3rd Qu.:15864
total_sales Max. :82500
operating_profit Min. : 0
operating_profit 1st Qu.: 1753
operating_profit Median : 3263
operating_profit Mean : 4895
operating_profit 3rd Qu.: 6192
operating_profit Max. :39000
operating_margin Min. :0.100
operating_margin 1st Qu.:0.350
operating_margin Median :0.410
operating_margin Mean :0.423
operating_margin 3rd Qu.:0.490
operating_margin Max. :0.800

Paso 6: Gráficos exploratorios

6.1 Ventas Totales por Region (torta)

# Calcular porcentaje por región
ventas_region <- ventas_region %>%
  mutate(pct = total_sales / sum(total_sales) * 100)

# Gráfico de torta con porcentajes
ggplot(ventas_region, aes(x = "", y = total_sales, fill = Region)) +
  geom_bar(stat = "identity", width = 1) +
  coord_polar(theta = "y") +
  geom_text(aes(label = paste0(round(pct,1), "%")),
            position = position_stack(vjust = 0.5),
            size = 4) +
  labs(title = "Ventas Totales por Region (%)") +
  theme_void()

6.1.1 Observacion Ventas Totales por Region

Podemos observar que las ventas por region la zona West (Oeste) tiene la mayor representacion en las ventas totales con un 30.3% le sigue la zona Northeaste (Nordeste) con una participacion del 20.9% , zona Southeast (Surdeste) con una participacion del 17.8% y South (Sur) con una participacion del 17.1%, Midwest (Medio Oeste) con una participacion del 13.9% de los ingresos totales por Region, sim embargo mostraremos la georeferienciacion de la distribucion por regiones donde podemos ver que a mayor territoriedad mayor porcentaje de venta .

6.1.2 Mapa por Regiones

# === Mapa interactivo por REGIÓN (solo región en tooltip y etiquetas) ===
library(dplyr)
library(plotly)

# Estados por región
NE <- c("CT","ME","MA","NH","NJ","NY","PA","RI","VT")
MW <- c("IL","IN","IA","KS","MI","MN","MO","NE","ND","OH","SD","WI")
SE <- c("FL","GA","AL","MS","TN","NC","SC")
S  <- c("DE","MD","VA","WV","KY","AR","LA","OK","TX")
W  <- c("AK","AZ","CA","CO","HI","ID","MT","NV","NM","OR","UT","WA","WY")

mapa_estados <- tibble(
  state  = c(NE, MW, S, SE, W),
  Region = c(rep("Northeast", length(NE)),
             rep("Midwest",   length(MW)),
             rep("South",     length(S)),
             rep("Southeast", length(SE)),
             rep("West",      length(W)))
)

# Colores fijos por región
colores_region <- c(
  "Midwest"   = "#F8766D",
  "Northeast" = "#B79F00",
  "South"     = "#00BA38",
  "Southeast" = "#00BFC4",
  "West"      = "#C77CFF"
)

# Choropleth categórico
fig <- plot_ly(
  data = mapa_estados,
  type = "choropleth",
  locationmode = "USA-states",
  locations = ~state,
  z = ~as.numeric(factor(Region)),
  colorscale = list(
    list(0, colores_region["Midwest"]),
    list(0.25, colores_region["Northeast"]),
    list(0.5, colores_region["South"]),
    list(0.75, colores_region["Southeast"]),
    list(1, colores_region["West"])
  ),
  showscale = FALSE,
  hovertemplate = "<b>Región:</b> %{customdata}<extra></extra>",
  customdata = mapa_estados$Region
)

# Etiquetas con el nombre de la región
fig <- fig %>%
  add_trace(
    type = "scattergeo",
    locationmode = "USA-states",
    locations = mapa_estados$state,
    text = mapa_estados$Region,
    mode = "text",
    textfont = list(color = "black", size = 9)
  )

# Layout
fig <- fig %>%
  layout(
    title = "Mapa interactivo de EE.UU. por Región",
    geo = list(scope = "usa")
  )

fig

6.2 Ventas por Método de Venta (barras)

# Calcular ventas totales y participación porcentual por canal
ventas_canal <- datos_adidas %>% 
  group_by(metodo_venta) %>% 
  summarise(ventas_totales = sum(total_sales, na.rm = TRUE), .groups = "drop") %>%
  mutate(
    participacion_pct = round(100 * ventas_totales / sum(ventas_totales), 2) # porcentaje
  )

# Mostrar tabla
kable(ventas_canal, 
      caption = "Ventas totales y participación porcentual por método de venta", 
      digits = 0) %>%
  kableExtra::kable_styling(full_width = FALSE)
Ventas totales y participación porcentual por método de venta
metodo_venta ventas_totales participacion_pct
In-store 35664375 30
Online 44965657 37
Outlet 39536618 33
# Gráfico de barras interactivas con porcentajes en tooltip
plot_ly(ventas_canal, x = ~metodo_venta, y = ~ventas_totales, type = "bar",
        text = ~paste("Participación:", participacion_pct, "%"),
        hoverinfo = "text+y",
        marker = list(color = "steelblue")) %>%
  layout(title = "Ventas totales y  participación por método de venta",
         xaxis = list(title = "Método de venta"),
         yaxis = list(title = "Ventas totales"))

6.2.1 Observacion Ventas Totales por metodo de ventas

Podemos observar que el canal Online es el canal líder y el mas rentable con 44,97 millones en ventas, lo que representa la mayor participación con un 37% del total de las ventas.

El canal Outlet ocupa el segundo lugar con 39,54 millones, mostrando que el canal de descuento también mueve un volumen muy alto en ventas de la compañia con una participacion del 33% de las ventas totales. esto puedo obedecer a los bajos precios y ofertas.

El canal In-store queda tercero con 35,66 millones, aunque sigue siendo un canal relevante. tiene el menor volumen, representando el 30% del total.

6.3 Relación precio–unidades vendidas (dispersión)

ggplot(datos_adidas, aes(x = price_per_unit, y = units_sold, color = metodo_venta)) +
  geom_point(alpha = 0.6) +
  geom_smooth(method = "loess", se = FALSE) +
  labs(title = "Relación precio–unidades vendidas",
       x = "Precio por unidad", y = "Unidades vendidas", color = "Método de venta") +
  theme_minimal()

# Correlación precio–unidades por canal de venta
correlaciones <- datos_adidas %>%
  group_by(metodo_venta) %>%
  summarise(
    correlacion = cor(price_per_unit, units_sold, use = "complete.obs"),
    .groups = "drop"
  )

# Mostrar tabla en el reporte
kable(correlaciones, caption = "Coeficiente de correlación entre precio y unidades vendidas por canal", digits = 3)
Coeficiente de correlación entre precio y unidades vendidas por canal
metodo_venta correlacion
In-store 0.359
Online 0.149
Outlet 0.393

6.3.1 Observaciones Relacion Precio unidades Vendidas

In-store nos muestra una tendencia positiva a precios más altos también se venden más unidades

Online tiene una tendencia más plana, con ligera subida esto nos muestra que el precio no define tanto el volumen, influyen otros factores ccomo pueden ser promociones o marketing digital.

Outlet presenta una curva curvilínea crece hasta un punto medio, pero luego se aplana o baja esto puede decir que los clientes buscan precios bajos por ser un outlet.

6.3.2 Correlaciones entre precio por unidad y unidades vendidas para Adidas por canal:

Tanto In-store como Outlet muestran correlaciones moderadas positivas: a medida que sube el precio, también las ventas en unidades crecen.

Online es mucho más inelástico al precio aquí hay oportunidad de trabajar estrategias digitales para mejorar.

6.4 Margen operativo (%): distribución y por producto

# Histograma margen
ggplot(datos_adidas, aes(x = margen_operativo_pct)) +
  geom_histogram(bins = 30, fill = "#2c7fb8", color = "white", alpha = 0.9) +
  geom_vline(aes(xintercept = mean(margen_operativo_pct, na.rm = TRUE)), linetype = 2) +
  labs(title = "Distribución del margen operativo (%)", x = "Margen operativo (%)", y = "Frecuencia") +
  theme_minimal()

6.4.1 Observaciones Histograma Margen Operativo

la concentración principal esta entre 35% y 50%, esto indica que típicamente los márgenes se mueven en ese rango de la media 42% Pocos casos con márgenes bajos (<20%) o muy altos (>70%).

6.5 Margen Operativo por Linea de Producto

# Boxplot por producto
ggplot(datos_adidas, aes(x = producto, y = margen_operativo_pct, fill = producto)) +
  geom_boxplot(alpha = 0.85, outlier.alpha = 0.5) +
  coord_flip() +
  labs(title = "Margen operativo (%) por línea de producto", x = NULL, y = "Margen operativo (%)") +
  theme_minimal() +
  theme(legend.position = "none")

6.5.1 Observaciones Margen Operactivo por Linea de Producto

En la Mediana del margen podemos observar:

Women’s Apparel la mediana está más alta entre 45–50%, lo que sugiere que esta línea suele ser más rentable.

Men’s Apparel Esta presenta muchos valores extremos, la mediana es menor que la de Women’s Apparel.

Footwear que es calzado tanto en hombres como mujeres, athletic/street, se concentran más en torno a márgenes medios entre 35–45%.

En la Dispersiónpodemos observar:

Women’s Apparel y Men’s Apparel muestran más dispersión variabilidad en rentabilidad según referencias. Footwear tiene un comportamiento más estable en márgenes.

podemos resumir que la ropa femenina (Women’s Apparel) parece ser la línea más rentable y consistente, el calzado (Footwear) mantiene márgenes más estables, pero no alcanza los niveles de Apparel. La ropa masculina (Men’s Apparel) presenta gran variabilidad aca abria que revisar las causas.

6.6 Relacion Ventas Totales Vs Utilidad Operativa

# Figura: Relación entre ventas totales y utilidad operativa (Adidas)
# Requiere: library(ggplot2); library(plotly)

coef_cor_adidas <- cor(
  datos_adidas$operating_profit,
  datos_adidas$total_sales,
  use = "complete.obs"
)

ggplotly(
  ggplot(datos_adidas, aes(x = total_sales, y = operating_profit)) +
    geom_point(color = "lightblue", alpha = 0.9, size = 2) +     # Puntos
    geom_smooth(method = "lm", color = "grey", se = TRUE) +      # Tendencia lineal
    labs(
      title = paste(
        "Figura . Relación entre ventas totales y utilidad operativa\nCoef. de correlación:",
        round(coef_cor_adidas, 2)
      ),
      x = "Ventas totales",
      y = "Utilidad operativa",
      caption = "Fuente: Datos de ventas Adidas"
    ) +
    theme_minimal() +
    theme(
      plot.title = element_text(size = 14, face = "bold", hjust = 0.5),
      axis.title = element_text(size = 12),
      axis.text  = element_text(size = 10)
    )
)

6.6.1 Observaciones ventas Totales Vs Utilidad Operativo

El análisis confirma que las ventas son un factor determinante de la utilidad operativa en Adidas, con una relación casi lineal y muy fuerte, esto implica que mantener el volumen de ventas es clave para sostener la rentabilidad.

Paso 7: Tablas resumen y ranking

margen_por_producto <- datos_adidas %>% 
  group_by(producto) %>% 
  summarise(
    n = n(),
    margen_prom_pct = mean(margen_operativo_pct, na.rm = TRUE),
    margen_p25 = quantile(margen_operativo_pct, 0.25, na.rm = TRUE),
    margen_p50 = median(margen_operativo_pct, na.rm = TRUE),
    margen_p75 = quantile(margen_operativo_pct, 0.75, na.rm = TRUE),
    .groups = "drop"
  ) %>% arrange(desc(margen_prom_pct))

kable(margen_por_producto, caption = "Resumen del margen operativo (%) por producto", digits = 2)
Resumen del margen operativo (%) por producto
producto n margen_prom_pct margen_p25 margen_p50 margen_p75
Men’s Street Footwear 1610 44.61 40 45 50
Women’s Apparel 1608 44.13 35 44 53
Women’s Athletic Footwear 1606 42.44 35 41 49
Men’s Apparel 1606 41.32 35 40 48
Women’s Street Footwear 1608 41.02 35 40 47
Men’s Athletic Footwear 1610 40.27 35 40 47
sessionInfo()
## R version 4.3.3 (2024-02-29 ucrt)
## Platform: x86_64-w64-mingw32/x64 (64-bit)
## Running under: Windows 10 x64 (build 19045)
## 
## Matrix products: default
## 
## 
## locale:
## [1] LC_COLLATE=Spanish_Colombia.utf8  LC_CTYPE=Spanish_Colombia.utf8   
## [3] LC_MONETARY=Spanish_Colombia.utf8 LC_NUMERIC=C                     
## [5] LC_TIME=Spanish_Colombia.utf8    
## 
## time zone: America/Bogota
## tzcode source: internal
## 
## attached base packages:
## [1] stats     graphics  grDevices utils     datasets  methods   base     
## 
## other attached packages:
## [1] stringr_1.5.1    tidyr_1.3.1      kableExtra_1.4.0 knitr_1.45      
## [5] plotly_4.10.4    ggplot2_3.5.2    dplyr_1.1.4      readxl_1.4.5    
## 
## loaded via a namespace (and not attached):
##  [1] sass_0.4.9        utf8_1.2.4        generics_0.1.3    xml2_1.3.6       
##  [5] lattice_0.22-5    stringi_1.8.3     digest_0.6.34     magrittr_2.0.3   
##  [9] evaluate_0.23     grid_4.3.3        fastmap_1.1.1     Matrix_1.6-5     
## [13] cellranger_1.1.0  jsonlite_1.8.8    mgcv_1.9-1        httr_1.4.7       
## [17] purrr_1.0.2       fansi_1.0.6       crosstalk_1.2.1   viridisLite_0.4.2
## [21] scales_1.3.0      lazyeval_0.2.2    jquerylib_0.1.4   cli_3.6.2        
## [25] rlang_1.1.3       splines_4.3.3     ellipsis_0.3.2    munsell_0.5.0    
## [29] withr_3.0.0       cachem_1.0.8      yaml_2.3.8        tools_4.3.3      
## [33] colorspace_2.1-0  vctrs_0.6.5       R6_2.5.1          lifecycle_1.0.4  
## [37] htmlwidgets_1.6.4 pkgconfig_2.0.3   pillar_1.9.0      bslib_0.6.1      
## [41] gtable_0.3.6      glue_1.7.0        data.table_1.15.0 systemfonts_1.2.2
## [45] xfun_0.42         tibble_3.2.1      tidyselect_1.2.1  highr_0.10       
## [49] rstudioapi_0.17.1 farver_2.1.1      nlme_3.1-164      htmltools_0.5.7  
## [53] labeling_0.4.3    rmarkdown_2.25    svglite_2.1.3     compiler_4.3.3