{r setup, include=FALSE} knitr::opts_chunk$set(echo = TRUE, results = "show", message = FALSE, warning = FALSE)
El presente informe desarrolla un análisis exploratorio de datos (EDA) sobre las ventas de productos de la marca ADIDAS.
El objetivo es identificar patrones de comportamiento comercial, evaluar la estructura de precios, analizar la demanda por categoría y comprender la relación entre precio y volumen vendido.
Este análisis permite generar conclusiones estratégicas para toma de decisiones en pricing, portafolio y expansión comercial.
library(readxl)
library(dplyr)
##
## Adjuntando el paquete: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
library(ggplot2)
library(plotly)
##
## Adjuntando el paquete: 'plotly'
## The following object is masked from 'package:ggplot2':
##
## last_plot
## The following object is masked from 'package:stats':
##
## filter
## The following object is masked from 'package:graphics':
##
## layout
library(scales)
library(knitr)
library(kableExtra)
##
## Adjuntando el paquete: 'kableExtra'
## The following object is masked from 'package:dplyr':
##
## group_rows
library(tidyr)
Se utiliza el archivo: Datos_Adidas.xlsx
datos <- read_excel("Datos_Adidas.xlsx")
id = 1:dim(datos)[1]
datos = data.frame(id, datos)
head(datos)
| id | Producto | Categoria | Precio | Unidades_vendidas | Ciudad | Fecha |
|---|---|---|---|---|---|---|
| 1 | NMD R1 | Tenis | 688153 | 16 | Cali | 2025-11-23 |
| 2 | Sudadera Essentials | Sudaderas | 261240 | 73 | Cali | 2025-06-19 |
| 3 | Sudadera Essentials | Sudaderas | 326518 | 71 | Bogotá | 2025-02-21 |
| 4 | Ultraboost 22 | Tenis | 366354 | 11 | Medellín | 2025-02-19 |
| 5 | Superstar Classic | Tenis | 408533 | 35 | Bogotá | 2025-08-08 |
| 6 | NMD R1 | Tenis | 549131 | 17 | Barranquilla | 2025-07-14 |
En esta sección se estructura la base de datos y se valida la correcta lectura de las variables clave: Producto, Categoría, Precio y Unidades Vendidas.
La categoría Tenis representa uno de los segmentos estratégicos dentro del portafolio ADIDAS, generalmente asociado a mayor ticket promedio y posicionamiento premium.
datos_sub <- datos %>%
filter(Categoria == "Tenis")
head(datos_sub)
| id | Producto | Categoria | Precio | Unidades_vendidas | Ciudad | Fecha |
|---|---|---|---|---|---|---|
| 1 | NMD R1 | Tenis | 688153 | 16 | Cali | 2025-11-23 |
| 4 | Ultraboost 22 | Tenis | 366354 | 11 | Medellín | 2025-02-19 |
| 5 | Superstar Classic | Tenis | 408533 | 35 | Bogotá | 2025-08-08 |
| 6 | NMD R1 | Tenis | 549131 | 17 | Barranquilla | 2025-07-14 |
| 7 | Ultraboost 22 | Tenis | 625806 | 80 | Medellín | 2025-10-13 |
| 8 | Ultraboost 22 | Tenis | 361363 | 85 | Cali | 2025-04-03 |
Los indicadores de centralidad permiten entender el comportamiento promedio del mercado dentro de la categoría.
cantidad_productos = nrow(datos_sub)
promedio_precio = mean(datos_sub$Precio, na.rm = TRUE)
promedio_unidades = mean(datos_sub$Unidades_vendidas, na.rm = TRUE)
resultado_prom = data.frame(cantidad_productos,
promedio_precio,
promedio_unidades)
resultado_prom
| cantidad_productos | promedio_precio | promedio_unidades |
|---|---|---|
| 90 | 547115.5 | 54.51111 |
Interpretación: - El precio promedio refleja el posicionamiento del portafolio. - Las unidades promedio indican el nivel de rotación. - La cantidad de registros muestra la profundidad del surtido analizado.
Las medianas ayudan a identificar si existen valores atípicos que estén distorsionando el promedio.
mediana_precio = median(datos_sub$Precio, na.rm = TRUE)
mediana_unidades = median(datos_sub$Unidades_vendidas, na.rm = TRUE)
resultado_med = data.frame(mediana_precio,
mediana_unidades)
resultado_med
| mediana_precio | mediana_unidades |
|---|---|
| 551167.5 | 51.5 |
Si la mediana es significativamente distinta al promedio, puede indicar presencia de productos premium o descuentos agresivos.
El análisis de dispersión permite evaluar qué tan homogénea es la estrategia de precios dentro de la categoría.
min_precio = min(datos_sub$Precio, na.rm = TRUE)
max_precio = max(datos_sub$Precio, na.rm = TRUE)
sd_precio = sd(datos_sub$Precio, na.rm = TRUE)
indic_precio = data.frame(promedio_precio,
mediana_precio,
min_precio,
max_precio,
sd_precio)
indic_precio
| promedio_precio | mediana_precio | min_precio | max_precio | sd_precio |
|---|---|---|---|---|
| 547115.5 | 551167.5 | 353470 | 735618 | 111031.1 |
Una desviación estándar alta sugiere un portafolio amplio que cubre diferentes niveles de precio (entrada, medio y premium).
El histograma permite observar la concentración de precios y detectar rangos predominantes.
grafico_hist <- ggplot(datos_sub, aes(x = Precio)) +
geom_histogram(binwidth = 50000,
fill = "#000000",
color = "white",
alpha = 0.9) +
scale_x_continuous(labels = label_dollar(prefix = "$", big.mark = ".")) +
labs(title = "Distribución de Precios - ADIDAS (Tenis)",
subtitle = "Concentración por rangos de precio",
x = "Precio (COP)",
y = "Cantidad de Productos") +
theme_minimal(base_size = 14) +
theme(plot.title = element_text(face = "bold"),
plot.subtitle = element_text(size = 12))
ggplotly(grafico_hist)
## Warning in prettyNum(.Internal(format(x, trim, digits, nsmall, width, 3L, :
## 'big.mark' y 'decimal.mark' son ambos '.', lo cual puede ser confuso
Este gráfico facilita identificar si el portafolio está concentrado en un rango específico o si existe dispersión estratégica.
Este análisis permite evaluar elasticidad precio-demanda.
grafico_dispersion <- ggplot(datos_sub, aes(x = Precio, y = Unidades_vendidas)) +
geom_point(size = 3, alpha = 0.7, color = "#1f77b4") +
geom_smooth(method = "lm", se = FALSE, color = "red", size = 1.2) +
scale_x_continuous(labels = label_dollar(prefix = "$", big.mark = ".")) +
labs(title = "Precio vs Unidades Vendidas",
subtitle = "Análisis de posible elasticidad",
x = "Precio (COP)",
y = "Unidades Vendidas") +
theme_minimal(base_size = 14) +
theme(plot.title = element_text(face = "bold"))
## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## ℹ Please use `linewidth` instead.
## This warning is displayed once per session.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
ggplotly(grafico_dispersion)
## `geom_smooth()` using formula = 'y ~ x'
## Warning in prettyNum(.Internal(format(x, trim, digits, nsmall, width, 3L, :
## 'big.mark' y 'decimal.mark' son ambos '.', lo cual puede ser confuso
Una pendiente negativa indicaría que precios más altos reducen la cantidad vendida. Una pendiente plana indicaría menor sensibilidad al precio (producto con mayor valor percibido).
Este análisis permite comparar el desempeño entre diferentes líneas de producto.
ventas_categoria <- datos %>%
group_by(Categoria) %>%
summarise(Total_unidades = sum(Unidades_vendidas, na.rm = TRUE),
Ingresos = sum(Precio * Unidades_vendidas, na.rm = TRUE))
grafico_barras <- ggplot(ventas_categoria,
aes(x = reorder(Categoria, Ingresos), y = Ingresos)) +
geom_col(fill = "#2ca02c") +
coord_flip() +
scale_y_continuous(labels = label_dollar(prefix = "$", big.mark = ".")) +
labs(title = "Ingresos Totales por Categoría",
subtitle = "Comparativo de desempeño comercial",
x = "Categoría",
y = "Ingresos (COP)") +
theme_minimal(base_size = 14) +
theme(plot.title = element_text(face = "bold"))
ggplotly(grafico_barras)
## Warning in prettyNum(.Internal(format(x, trim, digits, nsmall, width, 3L, :
## 'big.mark' y 'decimal.mark' son ambos '.', lo cual puede ser confuso
Aquí se identifican:
Este análisis permite:
La información obtenida puede ser utilizada para diseñar estrategias de crecimiento, promociones o redefinición de surtido.