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)

PASO 2: Cargar la base 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 estadístico de las variables financieras
resumen <- datos_col %>% 
  select(ventas_total, utilidad_operativa, margen_operativo ) %>% 
  summary()

resumen
##   ventas_total   utilidad_operativa margen_operativo
##  Min.   :    0   Min.   :    0      Min.   :0.100   
##  1st Qu.: 4065   1st Qu.: 1753      1st Qu.:0.350   
##  Median : 7804   Median : 3263      Median :0.410   
##  Mean   :12455   Mean   : 4895      Mean   :0.423   
##  3rd Qu.:15864   3rd Qu.: 6192      3rd Qu.:0.490   
##  Max.   :82500   Max.   :39000      Max.   :0.800
# 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 = "$",
      big.mark = ".",
      decimal.mark = ",",
      accuracy = 1
    ),
    unidades_vendidas = format(
      unidades_vendidas,
      big.mark = ".",
      decimal.mark = ",",
      scientific = FALSE
    ),
    utilidad_operativa = dollar(
      utilidad_operativa,
      prefix = "$",
      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 = "$",
      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 $120.166.650
Unidades vendidas 2.478.861
Utilidad operacional $47.224.968
Margen operativo promedio 39,30%
Precio promedio $48
# Crear resumen de ventas por región
ventas_region <- datos_col %>%
  group_by(region) %>%
  summarise(
    ventas_total = sum(ventas_total, na.rm = TRUE),
    .groups = "drop"
  ) %>%
  arrange(desc(ventas_total))

ggplot(ventas_region, aes(
  x = ventas_total / 1000000,
  y = reorder(region, ventas_total),
  fill = ventas_total
)) +
  geom_col(width = 0.55) +
  
  geom_text(
    aes(
      label = paste0("$", round(ventas_total / 1000000, 2), " M")
    ),
    hjust = -0.15,
    size = 4
  ) +
  
  scale_fill_gradient(
    low = "#9ecae1",
    high = "#08519c"
  ) +
  
  labs(
    title = "Ventas Totales por Región",
    subtitle = "Valor acumulado de ventas expresado en millones",
    x = "Ventas totales (millones)",
    y = "Región"
  ) +
  
  theme_minimal() +
  
  theme(
    panel.grid = element_blank(),       # Quita todas las líneas del fondo
    plot.title = element_text(
      size = 16,
      face = "bold"
    ),
    plot.subtitle = element_text(
      size = 11
    ),
    axis.title = element_text(
      size = 11,
      face = "bold"
    ),
    axis.text = element_text(
      size = 10
    ),
    legend.position = "none"
  ) +
  
  expand_limits(
    x = max(ventas_region$ventas_total / 1000000) * 1.15
  )

# Resumir la utilidad operativa por región
utilidad_region <- datos_col %>%
  group_by(region) %>%
  summarise(
    utilidad_operativa = sum(
      utilidad_operativa,
      na.rm = TRUE
    ),
    .groups = "drop"
  ) %>%
  arrange(desc(utilidad_operativa))
ggplot(utilidad_region, aes(
  x = utilidad_operativa / 1000000,
  y = reorder(region, utilidad_operativa),
  fill = utilidad_operativa
)) +
  geom_col(width = 0.55) +
  
  geom_text(
    aes(
      label = paste0("$", round(utilidad_operativa / 1000000, 2), " M")
    ),
    hjust = -0.15,
    size = 4
  ) +
  
  scale_fill_gradient(
    low = "#9ecae1",
    high = "#08519c"
  ) +
  
  labs(
    title = "Utilidad Operativa por Región",
    subtitle = "Valor acumulado de Utilidad Operativa expresado en millones",
    x = "Utilidad Operativa (millones)",
    y = "Región"
  ) +
  
  theme_minimal() +
  
  theme(
    panel.grid = element_blank(),       # Quita todas las líneas del fondo
    plot.title = element_text(
      size = 16,
      face = "bold"
    ),
    plot.subtitle = element_text(
      size = 11
    ),
    axis.title = element_text(
      size = 11,
      face = "bold"
    ),
    axis.text = element_text(
      size = 10
    ),
    legend.position = "none"
  ) +
  
  expand_limits(
    x = max(ventas_region$ventas_total / 1000000) * 1.15
  )

# Crear resumen de margen operativo por región
margen_region <- 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(
    margen_operativo = utilidad_operativa / ventas_total * 100
  ) %>%
  arrange(margen_operativo)
# Gráfico de barras horizontal
ggplot(
  margen_region,
  aes(
    x = margen_operativo,
    y = reorder(region, margen_operativo),
    fill = margen_operativo
  )
) +
  geom_col(width = 0.55) +
  geom_text(
    aes(
      label = paste0(
        format(
          round(margen_operativo, 2),
          decimal.mark = ",",
          nsmall = 2
        ),
        "%"
      )
    ),
    hjust = -0.15,
    size = 4,
    color = "#1F2937"
  ) +
  # Misma estructura de colores del gráfico anterior
  scale_fill_gradient(
    low = "#c6dbef",
    high = "#08306b"
  ) +
  labs(
    title = "Margen Operativo por Región",
    subtitle = "Relación entre la utilidad operativa y las ventas totales",
    x = "Margen operativo (%)",
    y = "Región"
  ) +
  theme_minimal() +
  theme(
    panel.grid = element_blank(),
    # Título en color negro
    plot.title = element_text(
      size = 16,
      face = "bold",
      color = "black"
    ),
    plot.subtitle = element_text(
      size = 11,
      color = "#4B5563"
    ),
    axis.title = element_text(
      size = 11,
      face = "bold",
      color = "#1F2937"
    ),
    axis.text = element_text(
      size = 10,
      color = "#374151"
    ),
    legend.position = "none"
  ) +
  expand_limits(
    x = max(
      margen_region$margen_operativo,
      na.rm = TRUE
    ) * 1.15
  )

# Resumir unidades vendidas por producto
unidades_producto <- datos_col %>%
  group_by(producto) %>%
  summarise(
    total_unidades = sum(unidades_vendidas, na.rm = TRUE),
    .groups = "drop"
  ) %>%
  arrange(desc(total_unidades))
# Paleta en escala de grises y azules
colores_grises_azules <- c(
  "#0B2D45",  # Azul marino
  "#164E70",  # Azul petróleo
  "#287A9F",  # Azul medio
  "#5B9DB5",  # Azul grisáceo
  "#8FA9B5",  # Gris azulado
  "#B8C2C8",  # Gris claro
  "#6B7280",  # Gris medio
  "#374151"   # Gris oscuro
)
# Repetir colores si hay más productos que colores definidos
colores_grises_azules <- rep(
  colores_grises_azules,
  length.out = nrow(unidades_producto)
)
# Gráfico de torta
plot_ly(
  unidades_producto,
  labels = ~producto,              # Nombres completos en la leyenda
  values = ~total_unidades,
  type = "pie",
  textinfo = "percent",            # Solo porcentajes dentro de la torta
  textposition = "inside",
  insidetextorientation = "radial",
  hovertemplate = paste(
    "<b>%{label}</b><br>",
    "Unidades vendidas: %{value:,}<br>",
    "Participación: %{percent}<extra></extra>"
  ),
  marker = list(
    colors = colores_grises_azules,
    line = list(
      color = "#FFFFFF",
      width = 2
    )
  )
) %>%
  layout(
    title = list(
      text = "Participación de unidades vendidas por producto",
      font = list(
        color = "#000000",
        size = 18,
        family = "Arial"
      )
    ),
    # Los nombres completos aparecen fuera de la torta,
    # dentro de la leyenda
    showlegend = TRUE,
    legend = list(
      title = list(
        text = "Productos"
      ),
      orientation = "v",
      x = 1,
      y = 0.5,
      font = list(
        size = 11,
        color = "#263238"
      )
    ),
    margin = list(
      l = 10,
      r = 220,
      t = 75,
      b = 10
    ),
    paper_bgcolor = "#FFFFFF",
    plot_bgcolor = "#FFFFFF"
  )
# 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(
    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(
        "$",
        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"
  ) +

  scale_fill_manual(
    values = c(
      "Ventas totales" = "#164E70",
      "Utilidad operativa" = "#8FA9B5"
    )
  ) +

  scale_y_continuous(
    labels = function(x) {
      paste0("$", format(x, decimal.mark = ",", nsmall = 0), " M")
    },
    expand = expansion(mult = c(0, 0.15))
  ) +

  labs(
    title = "Ventas y utilidad operativa por método de venta",
    subtitle = "Valores acumulados expresados en millones",
    x = "Método de venta",
    y = "Valor financiero",
    fill = "Indicador"
  ) +

  theme_minimal() +

  theme(
    panel.grid = element_blank(),

    plot.title = element_text(
      size = 16,
      face = "bold",
      color = "black"
    ),

    plot.subtitle = element_text(
      size = 11,
      color = "#5B6770"
    ),

    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"),
    legend.text = element_text(size = 10)
  )

Gráfico de barras

# Resumir las ventas por distribuidor y convertirlas a millones
ventas_distribuidor <- datos_col %>%
  group_by(distribuidor) %>%
  summarise(
    ventas_total = sum(ventas_total, na.rm = TRUE),
    .groups = "drop"
  ) %>%
  arrange(ventas_total) %>%
  mutate(
    ventas_millones = ventas_total / 1000000
  )

# Paleta de azules vivos
colores_azules <- colorRampPalette(
  c(
    "#A6CEE3",
    "#5DADE2",
    "#3498DB",
    "#2171B5",
    "#08519C"
  )
)(nrow(ventas_distribuidor))

# Gráfico horizontal sin valores al lado de las barras
grafico_barras_ingresos <- plot_ly(
  ventas_distribuidor,
  x = ~ventas_millones,
  y = ~reorder(distribuidor, ventas_millones),
  type = "bar",
  orientation = "h",

  marker = list(
    color = colores_azules,
    line = list(
      color = "#FFFFFF",
      width = 1
    )
  ),

  # Los valores solo aparecen al pasar el cursor
  hovertemplate = paste(
    "<b>%{y}</b><br>",
    "Ventas: $%{x:.2f} M<extra></extra>"
  )
) %>%
  layout(
    title = list(
      text = "Figura 1. Ventas de Adidas por distribuidor",
      font = list(
        color = "#000000",
        size = 18,
        family = "Arial"
      ),
      x = 0.05
    ),

    xaxis = list(
      title = list(
        text = "Ventas totales (millones)",
        font = list(
          color = "#1F2937",
          size = 13
        )
      ),
      tickprefix = "$",
      ticksuffix = " M",
      tickformat = ".2f",
      tickfont = list(
        color = "#374151",
        size = 11
      ),
      showgrid = FALSE,
      zeroline = FALSE,
      showline = FALSE
    ),

    yaxis = list(
      title = list(
        text = "Distribuidor",
        font = list(
          color = "#1F2937",
          size = 13
        )
      ),
      tickfont = list(
        color = "#374151",
        size = 11
      ),
      showgrid = FALSE,
      zeroline = FALSE,
      showline = FALSE
    ),

    bargap = 0.60,

    margin = list(
      l = 150,
      r = 40,
      t = 90,
      b = 75
    ),

    paper_bgcolor = "#FFFFFF",
    plot_bgcolor = "#FFFFFF"
  )

# Mostrar gráfico
grafico_barras_ingresos
# Diagrama de torta interactivo - Participacion de Ventas totales por Metodo 
unidades_producto <- datos_col %>%
  group_by(metodo_venta) %>%
  summarise(ventas_total = sum(ventas_total, na.rm = TRUE))

plot_ly(unidades_producto,
        labels = ~metodo_venta,
        values = ~ventas_total,
        type = 'pie',
        textinfo = 'label+percent',
        insidetextorientation = 'radial',
        marker = list(line = list(color = '#FFFFFF', width = 1))) %>%
  layout(title = "Figura X. Participacion de Ventas totales por Metodo",
         showlegend = TRUE)
# Crear y mostrar el boxplot interactivo
grafico <- ggplot(datos_col, 
                  aes(x = metodo_venta, 
                      y = ventas_total,
                      fill = metodo_venta,
                      text = paste(
                        "Método:", metodo_venta,
                        "<br>Unidades vendidas:", ventas_total,
                        "<br>Producto:", producto,
                        "<br>Ciudad:", ciudad,
                        "<br>Distribuidor:", distribuidor
                      ))) +
  
  geom_boxplot() +
  
  labs(
    title = "Distribución de Ventas total por método de venta",
    x = "Método de venta",
    y = "Ventas total"
  ) +
  
  theme_minimal() +
  
  theme(
    legend.position = "none",
    plot.title = element_text(hjust = 0.5)
  )

ggplotly(grafico, tooltip = "text")

Correlación-Dispersión

En la Figura 5. se observa una fuerte correlación positiva entre los ingresos y la utilidad operacional, con un coeficiente de correlación de 0.99.

Esto indica que a medida que los ingresos aumentan, la utilidad operacional también crece en casi la misma proporción.

# Crear gráfico interactivo con correlación
ggplotly(
  ggplot(datos_col, aes(x = precio_unidad, y = unidades_vendidas)) +
    geom_point(color = "lightblue", alpha = 0.9, size = 2) +  # Puntos con color y transparencia
    geom_smooth(method = "lm", color = "grey", se = TRUE) +  # Línea de tendencia lineal
    labs(
      title = paste("Figura 5. Relación entre Precio por Unidad y Unidades Vendidas \nCoef. de correlación: ", 
                    round(cor(datos_col$precio_unidad, datos_col$unidades_vendidas, use = "complete.obs"), 2)),
      x = "Precio Unidad (miles de pesos)",
      y = "Unidades Vendidas (Miles de pesos)",
      caption = "Fuente: Datos financieros"
    ) +
    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)
    )
)
# Crear gráfico interactivo con correlación
ggplotly(
  ggplot(datos_col, aes(x = ventas_total, y = utilidad_operativa)) +
    geom_point(color = "lightblue", alpha = 0.9, size = 2) +  # Puntos con color y transparencia
    geom_smooth(method = "lm", color = "grey", se = TRUE) +  # Línea de tendencia lineal
    labs(
      title = paste("Figura 5. Relación entre Ventas Totales y Utilidad Operativa \nCoef. de correlación: ", 
                    round(cor(datos_col$ventas_total, datos_col$utilidad_operativa, use = "complete.obs"), 2)),
      x = "ventas_total (miles de pesos)",
      y = "Utilidad_operativa (Miles de pesos)",
      caption = "Fuente: Datos financieros"
    ) +
    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)
    )
)
# Resumir las ventas por producto y región
heatmap_producto_region <- datos_col %>%
  group_by(producto, region) %>%
  summarise(
    ventas_total = sum(ventas_total, na.rm = TRUE),
    .groups = "drop"
  ) %>%
  pivot_wider(
    names_from = region,
    values_from = ventas_total,
    values_fill = 0
  )
# Conservar los nombres de los productos
productos <- heatmap_producto_region$producto
# Convertir los valores a una matriz numérica
matriz_heatmap <- heatmap_producto_region %>%
  select(-producto) %>%
  as.matrix()
# Heatmap con escala de colores fríos a cálidos
grafico_heatmap <- plot_ly(
  x = colnames(matriz_heatmap),
  y = productos,
  z = matriz_heatmap,
  type = "heatmap",
  colorscale = list(
    list(0.00, "#2166AC"),  # Azul: valores bajos
    list(0.25, "#67A9CF"),  # Azul claro
    list(0.50, "#FFFFBF"),  # Amarillo: valores intermedios
    list(0.75, "#F4A582"),  # Naranja claro
    list(1.00, "#B2182B")   # Rojo: valores altos
  ),
  colorbar = list(
    title = "Ventas",
    tickprefix = "$",
    tickformat = ",.0f"
  ),
  hovertemplate = paste(
    "<b>Producto:</b> %{y}<br>",
    "<b>Región:</b> %{x}<br>",
    "<b>Ventas:</b> $%{z:,.0f}<extra></extra>"
  )
) %>%
  layout(
    title = list(
      text = "Mapa de calor de ventas por producto y región",
      font = list(
        color = "#000000",
        size = 18,
        family = "Arial"
      ),
      x = 0.05
    ),
    xaxis = list(
      title = "Región",
      tickfont = list(
        color = "#374151",
        size = 11
      ),
      showgrid = FALSE
    ),
    yaxis = list(
      title = "Producto",
      tickfont = list(
        color = "#374151",
        size = 11
      ),
      showgrid = FALSE
    ),
    paper_bgcolor = "#FFFFFF",
    plot_bgcolor = "#FFFFFF",
    margin = list(
      l = 160,
      r = 100,
      t = 90,
      b = 80
    )
  )
# Mostrar el heatmap
grafico_heatmap
# Crear gráfico interactivo con correlación
ggplotly(
  ggplot(datos_col, aes(x = margen_operativo, y = utilidad_operativa)) +
    geom_point(color = "purple", alpha = 0.8, size = 2) +  # Puntos con color y transparencia
    geom_smooth(method = "loess", color = "grey", se = TRUE) +  # Línea de tendencia lineal
    labs(
      title = paste("Figura 5. Relación entre Margen Operativo Y Utilidad Operacional\nCoef. de correlación: ", 
                    round(cor(datos_col$margen_operativo, datos_col$utilidad_operativa, use = "complete.obs"), 2)),
      x = "Margen Operativo",
      y = "Utilidad Operativa",
      caption = "Fuente: Datos de Vivienda"
    ) +
    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)
    )
)