Jaime Gutiérrez, Msc., PhD (Docente en Ciencia de Datos)
Fecha de publicación
16 de marzo de 2025
Resumen
Este estudio realiza un análisis exploratorio de datos sobre patrones de compra un retail de Estados Unidos, explorando categorías de producto, ubicación geográfica y ventas. Mediante técnicas descriptivas y visualizaciones, se identifican tendencias que mejoran la comprensión del comportamiento del consumidor.
Palabras clave: Análisis exploratorio de datos, retail, comportamiento del consumidor, patrones de compra.
1Carga de Datos desde Google Drive
El dataset utilizado en este análisis se obtuvo de Kaggle y se ha almacenado en Google Drive para facilitar su acceso y procesamiento.
Código
# ID del archivo en Google Drivefile_id <-"135RWVsM2YO_XahdI0LKYmg5oDrokGnfB"# Descargar el archivodrive_download(as_id(file_id), path ="data2.csv", overwrite =TRUE)# Cargar el CSV en un data framedf <-read_csv("data2.csv", col_types =cols(`Row ID`=col_integer(), `Order Date`=col_date(format ="%d/%m/%Y"), `Ship Date`=col_date(format ="%d/%m/%Y"), `Postal Code`=col_character()))# Verificación de carga correctaif (nrow(df) >0) {cat("Datos cargados correctamente. Número de registros:", nrow(df), "\n")} else {cat("⚠️ Error en la carga de datos.")}
Datos cargados correctamente. Número de registros: 9800
# Mostrar el número de filas y columnascat("El Dataset tiene", nrow(df), "registros y", ncol(df), "columnas")
El Dataset tiene 9800 registros y 18 columnas
2.3Valores Nulos
En el proceso de limpieza de datos, se realizó un análisis de valores nulos en cada una de las variables del conjunto de datos. Se identificó que, de un total de 18 variables, únicamente la columna “Postal Code” presentaba valores faltantes, con un total de 11 registros nulos.
Código
# Contar valores nulos por columnatibble::tibble(Variable =names(df), Nulos =colSums(is.na(df))) %>%arrange(desc(Nulos))
# A tibble: 18 × 2
Variable Nulos
<chr> <dbl>
1 Postal Code 11
2 Row ID 0
3 Order ID 0
4 Order Date 0
5 Ship Date 0
6 Ship Mode 0
7 Customer ID 0
8 Customer Name 0
9 Segment 0
10 Country 0
11 City 0
12 State 0
13 Region 0
14 Product ID 0
15 Category 0
16 Sub-Category 0
17 Product Name 0
18 Sales 0
Dado que el número de registros afectados representa un porcentaje mínimo del total de datos (aproximadamente 0.11% de 9800 registros), se decidió eliminar estos registros sin afectar la integridad del análisis. Esta decisión se tomó considerando que la ausencia de estos valores no impacta significativamente en las conclusiones generales del estudio.
El resto de las variables no presentaron valores nulos, lo que indica que el conjunto de datos se encuentra en un estado adecuado para el análisis exploratorio sin necesidad de aplicar técnicas adicionales de imputación de datos.
Código
df <- df %>%drop_na() # Elimina todas las filas con al menos un NA
Se valida que los datos hayan sido eliminados.
Código
# Contar valores nulos por columnatibble::tibble(Variable =names(df), Nulos =colSums(is.na(df))) %>%arrange(desc(Nulos))
# A tibble: 18 × 2
Variable Nulos
<chr> <dbl>
1 Row ID 0
2 Order ID 0
3 Order Date 0
4 Ship Date 0
5 Ship Mode 0
6 Customer ID 0
7 Customer Name 0
8 Segment 0
9 Country 0
10 City 0
11 State 0
12 Postal Code 0
13 Region 0
14 Product ID 0
15 Category 0
16 Sub-Category 0
17 Product Name 0
18 Sales 0
2.4Verificación la naturaleza de las variables
Durante el proceso de lectura y preprocesamiento del conjunto de datos, se verificaron los tipos de datos de cada variable para garantizar su correcta interpretación y manipulación en el análisis. Se identificó lo siguiente:
Las variables que representan identificadores únicos (como Row ID, Order ID, Customer ID, Product ID) están correctamente almacenadas como caracteres o enteros, lo que permite su uso adecuado en uniones o filtros sin afectar los cálculos numéricos.
Las variables de fecha (Order Date y Ship Date) fueron correctamente asignadas al tipo Date, lo que facilita su uso en análisis temporales y cálculos de intervalos.
Las variables categóricas, como Ship Mode, Segment, Country, City, State, Region, Category, Sub-Category y Product Name, están representadas como caracteres, permitiendo su correcta clasificación y segmentación.
La variable Sales se encuentra correctamente definida como numérica, lo que permite realizar operaciones estadísticas y cálculos de métricas sin necesidad de conversión de tipo de datos.
Código
# Identificar el tipo de cada variable en dfdata_types <-sapply(df, class)#Crear tabla interactiva para identificar el tipo de cada variabledatatable( tibble::tibble(Variable =names(df), Tipo = data_types), options =list(paging =FALSE, # Desactiva la paginación (elimina "Next" y "Previous")scrollY ="400px", # Permite desplazamiento vertical si es necesariodom ='t'# Solo muestra la tabla, sin controles adicionales ),class ="display nowrap compact")
Este análisis asegura que los datos están correctamente estructurados y listos para su exploración sin la necesidad de ajustes adicionales en los tipos de datos.
2.5Resumen Estadístico
Resumen Estadístico de Variables Numéricas
Se realizó un análisis descriptivo de las variables numéricas del conjunto de datos, destacando medidas de tendencia central y dispersión para comprender su distribución.
Row ID: Se observa que Row ID es un identificador secuencial, con valores que van desde 1 hasta 9800. De hecho los cuartiles sugieren una distribución equitativa de los registros dentro del rango de valores.
Sales: El valor mínimo registrado es 0.444, mientras que el máximo asciende a 22,638.48, lo que sugiere una alta variabilidad en las ventas. La media (230.116) es notablemente mayor que la mediana (54.384), lo que indica la presencia de valores extremos (outliers) que pueden estar afectando la distribución. El primer cuartil (17.248) y el tercer cuartil (210.392) muestran que la mayoría de los datos se concentran en valores más bajos, con algunas ventas excepcionalmente altas. Por lo tanto requiere un análisis adicional que permita identificar y tratar posibles outliers.
Código
# Filtrar solo variables numéricasdf_numeric <- df %>%select(where(is.numeric))# Obtener el resumen estadísticosummary_table <-as.data.frame(summary(df_numeric))# Transformar la tabla para que las métricas sean columnassummary_table <- summary_table %>%separate(Freq, into =c("Statistic", "Value"), sep =":") %>%# Separar nombre de métricapivot_wider(names_from ="Statistic", values_from ="Value") # Convertir métricas en columnas# Formatear la tabla con kable()kable(summary_table, format ="html", caption ="Resumen Estadístico de Variables Numéricas") %>%kable_styling(full_width =FALSE, bootstrap_options =c("striped", "hover", "condensed", "responsive"))
Resumen Estadístico de Variables Numéricas
Var1
Var2
Min.
1st Qu.
Median
Mean
3rd Qu.
Max.
Row ID
1
2449
4896
4897
7344
9800
Sales
0.444
17.248
54.384
230.116
210.392
22638.480
Resumen Estadístico de Variables Categóricas
Se realizó un análisis de las variables categóricas para identificar la cantidad de valores únicos, la moda (valor más frecuente) y su frecuencia dentro del conjunto de datos. A continuación, se presentan los hallazgos más relevantes:
Diversidad de Registros: Existen 4916 órdenes únicas (Order ID), lo que indica que el conjunto de datos incluye múltiples transacciones individuales. Se registran 793 clientes únicos, lo que sugiere que algunos clientes han realizado múltiples compras. La base de datos abarca 529 ciudades y 48 estados, lo que refleja una amplia distribución geográfica de las ventas.
Distribución de las Categorías: La categoría con más registros es “Office Supplies”, con 5903 registros, lo que sugiere que puede ser la que más productos vendidos tenga. Dentro de las subcategorías, “Binders” es la más frecuente (1492 registros), lo que indica su popularidad dentro del catálogo. El producto más común es “Staple envelope”, con 47 registros.
Frecuencia de Valores Más Comunes: El modo de Ship Mode es Standard Class, que representa 5849 pedidos, lo que indica que la mayoría de los envíos utilizan este método. New York City es la ciudad con más transacciones (891 registros), mientras que California es el estado con mayor cantidad de ventas (1946 registros). La región “West” domina con 3140 registros, lo que podría indicar una mayor actividad comercial en esta zona.
Código
# Instalar paquetes si no están presentesif (!requireNamespace("kableExtra", quietly =TRUE)) install.packages("kableExtra")if (!requireNamespace("dplyr", quietly =TRUE)) install.packages("dplyr")# Cargar librerías necesariaslibrary(dplyr)library(knitr)library(kableExtra)# Filtrar solo variables categóricasdf_categorical <- df %>%select(where(is.character))# Crear una tabla con valores únicos, moda, frecuencia de la moda y total de registrossummary_table <- df_categorical %>%summarise(Variable =names(.),Unicos =sapply(., n_distinct),Moda =sapply(., function(x) names(sort(table(x), decreasing =TRUE)[1])),Frecuencia_Moda =sapply(., function(x) max(table(x))),Total_Registros =n() )# Formatear la tabla con kable()kable(summary_table, format ="html", caption ="Resumen de Variables Categóricas") %>%kable_styling(full_width =FALSE, bootstrap_options =c("striped", "hover", "condensed", "responsive"))
Resumen de Variables Categóricas
Variable
Unicos
Moda
Frecuencia_Moda
Total_Registros
Order ID
4916
CA-2018-100111
14
9789
Ship Mode
4
Standard Class
5849
9789
Customer ID
793
WB-21850
35
9789
Customer Name
793
William Brown
35
9789
Segment
3
Consumer
5096
9789
Country
1
United States
9789
9789
City
529
New York City
891
9789
State
48
California
1946
9789
Postal Code
626
10035
253
9789
Region
4
West
3140
9789
Product ID
1860
OFF-PA-10001970
18
9789
Category
3
Office Supplies
5903
9789
Sub-Category
17
Binders
1492
9789
Product Name
1848
Staple envelope
47
9789
Resumen Estadístico de Variables Tiempo
Se realizó un análisis exploratorio de las variables de fecha presentes en el conjunto de datos, específicamente Order Date (fecha de pedido) y Ship Date (fecha de envío). A continuación, se presentan los hallazgos clave:
Rango temporal: Los pedidos registrados en la base de datos abarcan desde el 3 de enero de 2015 hasta el 30 de diciembre de 2018, cubriendo un período de casi 4 años. Los envíos se realizaron entre el 7 de enero de 2015 y el 5 de enero de 2019, lo que sugiere que algunos pedidos fueron enviados a inicios del año siguiente a su compra.
Distribución de las Fechas: La mediana de las fechas de pedido es el 26 de junio de 2017, lo que indica que la mayoría de las transacciones se concentran en la segunda mitad del período analizado. De manera similar, la mediana de las fechas de envío es el 29 de junio de 2017, lo que sugiere que los envíos siguen un patrón similar a los pedidos. La media de ambas fechas es cercana a mayo de 2017, lo que confirma que la mayor parte de los pedidos se realizaron en este período.
Intervalo entre pedido y envío: En promedio, los envíos se realizan pocos días después del pedido. La diferencia entre la mediana de Order Date y Ship Date es de 3 días, lo que indica un proceso de entrega relativamente rápido y consistente.
Código
# Filtrar solo variables numéricas#df_not_numeric <- df %>% select(where(is.Date))df_dates <- df %>%select(where(function(x) inherits(x, "Date") |inherits(x, "POSIXt")))# Obtener el resumen estadístico en formato de tablasummary_table <-as.data.frame(summary(df_dates))# Transformar la tabla para que las métricas sean columnassummary_table <- summary_table %>%separate(Freq, into =c("Statistic", "Value"), sep =":") %>%# Separar nombre de métricapivot_wider(names_from ="Statistic", values_from ="Value") # Convertir métricas en columnas# Formatear la tabla con kable()kable(summary_table, format ="html", caption ="Resumen Estadístico de Variables no Numéricas") %>%kable_styling(full_width =FALSE, bootstrap_options =c("striped", "hover", "condensed", "responsive"))
Resumen Estadístico de Variables no Numéricas
Var1
Var2
Min.
1st Qu.
Median
Mean
3rd Qu.
Max.
Order Date
2015-01-03
2016-05-23
2017-06-26
2017-05-01
2018-05-15
2018-12-30
Ship Date
2015-01-07
2016-05-27
2017-06-29
2017-05-05
2018-05-19
2019-01-05
3Distribución de Variables Categóricas
Se realizó un análisis exploratorio de las variables categóricas mediante gráficos de barras, lo que permitió identificar la distribución de cada categoría dentro de las diferentes dimensiones del conjunto de datos. No se consideran Order ID, Customer ID, Customer Name, City, Postal Code, Product Name, Product ID porque tienen demasiadas categorías.
Ship Mode (Modo de Envío): La opción de envío más utilizada es “Standard Class”, con una clara mayoría de registros. El método “Same Day” es el menos frecuente, lo que indica que la entrega inmediata no es una opción de envío común para la mayoría de los pedidos.
Segment (Segmento de Cliente): El segmento “Consumer” es el predominante en las ventas, con una mayoría significativa de registros. “Home Office” tiene la menor participación, lo que sugiere que el mercado de oficinas en casa es el menos representado en este conjunto de datos.
State (Estado de Venta): California es el estado con mayor número de registros, seguido por Nueva York y Pensilvania. La distribución es altamente desigual, con algunos estados acumulando una gran cantidad de ventas y otros con muy pocas transacciones registradas.
Region (Región de Venta): La Región Oeste (“West”) tiene la mayor cantidad de transacciones, seguida de Este (“East”) y Central. La Región Sur (“South”) tiene la menor cantidad de registros, lo que podría indicar un menor volumen de ventas en esa área.
Category (Categoría de Producto): “Office Supplies” es la categoría más vendida, superando ampliamente a “Furniture” y “Technology”. Esto sugiere que el negocio se centra en la venta de suministros de oficina más que en productos tecnológicos o muebles.
Sub-Category (Subcategoría de Producto): “Binders”, “Paper” y “Furnishings” son las subcategorías con mayor cantidad de registros. Subcategorías como “Copiers”, “Machines” y “Fasteners” tienen la menor cantidad de ventas registradas.
Este análisis confirma que hay una concentración de ventas en ciertos segmentos y categorías, con un enfoque claro en suministros de oficina y consumidores individuales. Además, la distribución geográfica sugiere que algunas regiones tienen una mayor demanda de productos que otras.
Código
# Instalar paquetes si no están presentesif (!requireNamespace("ggplot2", quietly =TRUE)) install.packages("ggplot2")if (!requireNamespace("purrr", quietly =TRUE)) install.packages("purrr")if (!requireNamespace("forcats", quietly =TRUE)) install.packages("forcats")# Cargar libreríaslibrary(ggplot2)library(dplyr)library(purrr)library(forcats) # Para ordenar factores por frecuencia# Filtrar solo variables categóricas y excluir ciertas columnasdf_categorical <- df %>%select(where(is.character), -c(`Order ID`, `Customer ID`, `Customer Name`, City, `Postal Code`, `Product Name`, `Product ID`))# Crear un gráfico de conteo para cada variable categórica (ordenando de mayor a menor)plots_cat <-map(names(df_categorical), function(var) {ggplot(df, aes(x =fct_infreq(.data[[var]]))) +# Ordenar de mayor a menorgeom_bar(fill ="steelblue", color ="black", alpha =0.8) +theme_minimal(base_size =14) +labs(title =paste("Conteo de:", var), x = var, y ="Frecuencia") +theme(axis.text.x =element_text(size =12, angle =45, hjust =1), # Rotar etiquetas si son largasaxis.text.y =element_text(size =12) )})# Mostrar los gráficosplots_cat
[[1]]
[[2]]
[[3]]
[[4]]
[[5]]
[[6]]
[[7]]
4Análisis de Datos Atípicos
Se profundizó en el análisis de la variable Sales mediante un histograma y un boxplot para evaluar su distribución y la presencia de valores atípicos.
Distribución de las Ventas: El histograma muestra una distribución altamente sesgada a la derecha, con la mayoría de las observaciones concentradas en valores bajos de ventas. La mayoría de los valores de ventas se encuentran por debajo de 500, mientras que existen algunos registros con valores significativamente más altos, alcanzando hasta 22,638.48.
Detección de Valores Atípicos: El boxplot confirma la presencia de múltiples outliers en la parte superior de la distribución. La gran cantidad de puntos alejados del cuerpo principal del boxplot sugiere que hay transacciones con ventas inusualmente altas en comparación con el resto de los datos.
Código
# Instalar si es necesarioif (!requireNamespace("ggplot2", quietly =TRUE)) install.packages("ggplot2")library(ggplot2)# Crear un histograma solo para la variable 'Sales'ggplot(df, aes(x = Sales)) +geom_histogram(bins =25, alpha =0.7, color ="black", fill ="gray") +theme_minimal(base_size =14) +labs(title ="Distribución de Sales", x ="Sales", y ="Frecuencia") +theme(axis.text.x =element_text(size =12),axis.text.y =element_text(size =12) )
Código
# Instalar si es necesarioif (!requireNamespace("ggplot2", quietly =TRUE)) install.packages("ggplot2")library(ggplot2)# Generar boxplot solo para la variable 'Sales'ggplot(df, aes(y = Sales)) +# Eje y para variable numéricageom_boxplot(fill ="tomato", color ="black", alpha =0.7) +theme_minimal(base_size =14) +labs(title ="Boxplot de Sales", y ="Sales", x ="Valores") +# Etiqueta para eje xcoord_flip() +# Invierte los ejes para que sea horizontaltheme(axis.text.y =element_text(size =12))
La presencia de outliers podría influir en medidas estadísticas como la media, haciéndola menos representativa del comportamiento general de las ventas. Se recomienda analizar estos valores atípicos para determinar si corresponden a transacciones legítimas o errores en los datos.
Dependiendo del objetivo del análisis, se pueden aplicar técnicas como la transformación logarítmica o la winsorización para reducir el impacto de los valores extremos en los resultados.
Sin embargo, de acuerdo a esto, las ventas tienen una distribución altamente asimétrica, con la mayoría de los valores concentrados en montos pequeños y algunas transacciones excepcionales de alto valor.
5 Análisis Temporal de las ventas
Se realizó un análisis de la evolución de las ventas a lo largo del tiempo utilizando una serie temporal mensual. A continuación, se presentan los hallazgos clave:
Tendencias Generales: Se observa una tendencia creciente en las ventas a lo largo del período analizado, lo que indica un aumento progresivo en el volumen de transacciones. Hacia el final del período, las ventas alcanzan sus valores más altos, lo que sugiere una posible expansión del negocio o un incremento en la demanda.
Patrones de Estacionalidad: La serie temporal muestra un patrón cíclico, con picos recurrentes seguidos de caídas en las ventas. Estos ciclos podrían estar relacionados con temporadas de alta demanda, como eventos promocionales, períodos festivos o tendencias de compra estacionales.
Se recomienda un análisis más detallado para identificar si estos picos coinciden con eventos específicos, como Black Friday, Navidad u otras promociones comerciales.
Variabilidad y Fluctuaciones: Se evidencian fluctuaciones significativas entre meses, lo que sugiere que las ventas no son uniformes a lo largo del tiempo. Las caídas abruptas después de los picos pueden estar relacionadas con la finalización de períodos promocionales o cambios en la demanda del mercado.
Código
# Asegurar que la columna de fecha esté en formato correctodf <- df %>%mutate(`Order Date`=as.Date(`Order Date`))# Agregar una columna de año-mes para analizar la tendencia mensualdf <- df %>%mutate(Month_Year =format(`Order Date`, "%Y-%m"))# Graficar evolución de ventas por mesggplot(df %>%group_by(Month_Year) %>%summarise(Total_Sales =sum(Sales)), aes(x = Month_Year, y = Total_Sales, group =1)) +geom_line(color ="blue", size =1) +theme_minimal(base_size =14) +labs(title ="Tendencia de Ventas Mensuales", x ="Fecha", y ="Ventas") +theme(axis.text.x =element_text(angle =45, hjust =1))
6 Variables que más impactan las ventas
Para determinar qué variables categóricas tienen una influencia significativa en las ventas, se realizó un Análisis de Varianza (ANOVA). Este método permite evaluar si existen diferencias significativas en las ventas según cada categoría dentro de las variables analizadas.
Hipótesis Formuladas
Para cada variable categórica analizada, el ANOVA evalúa la siguiente hipótesis:
Hipótesis Nula (H₀): No hay diferencias significativas en las ventas entre los diferentes grupos dentro de la variable categórica. Es decir, la variable no tiene un impacto significativo en las ventas.
Hipótesis Alternativa (H₁): Al menos un grupo dentro de la variable categórica tiene un efecto significativo en las ventas, lo que indica que la variable influye en los montos de venta.
Código
# Filtrar solo variables categóricas, excluyendo identificadores irrelevantescategorical_vars <- df %>%select(where(is.character)) %>%select(-c(`Order ID`, `Customer ID`, `Customer Name`, City, `Postal Code`, `Product Name`, `Product ID`, `Country`)) %>%names()# Definir una función para realizar ANOVA en cada variable categóricaanova_results <-map(categorical_vars, function(cat_var) { df_filtered <- df %>%mutate(!!sym(cat_var) :=as.factor(.data[[cat_var]])) # Convertir a factor# Agregar backticks (`) a nombres con espacios formula_anova <-as.formula(paste("Sales ~ `", cat_var, "`", sep =""))# Ejecutar ANOVA anova_model <-aov(formula_anova, data = df_filtered)# Extraer p-valor p_value <-summary(anova_model)[[1]][["Pr(>F)"]][1]# Retornar en formato de tablareturn(data.frame(Variable = cat_var, P_Value = p_value))})# Convertir los resultados en un DataFrame ordenadoanova_df <-bind_rows(anova_results) %>%arrange(P_Value)# Mostrar los resultadosprint(anova_df)
Los valores de P-Value obtenidos indican qué variables tienen un impacto estadísticamente significativo en las ventasn (se rechaza la hipótesis nula):
Sub-Category (P-Value = 0.000000)
Category (P-Value ≈ 1.67e-111)
State (P-Value ≈ 0.002)
Variables con P-Value Alto que indican que no hay evidencia fuerte de que afecte significativamente las ventas.
Month_Year (P-Value ≈ 0.448)
Region (P-Value ≈ 0.490)
Segment (P-Value ≈ 0.586)
Ship Mode (P-Value ≈ 0.965)
7 Exporto Dataframe
Para poder analizar los resultados en otras herramientas, se exporta el dataframe
Código
write_csv(df, "dataset_exportado.csv")
Cómo citar
BibTeX
@online{camacho_guzmán2025,
author = {Camacho Guzmán, Sharon and Gutiérrez, Msc., PhD (Docente en
Ciencia de Datos), Jaime},
title = {Evidencia de Aprendizaje 1 - Análisis Descriptivo},
date = {2025-03-16},
langid = {es},
abstract = {Este estudio realiza un análisis exploratorio de datos
sobre patrones de compra un retail de Estados Unidos, explorando
categorías de producto, ubicación geográfica y ventas. Mediante
técnicas descriptivas y visualizaciones, se identifican tendencias
que mejoran la comprensión del comportamiento del consumidor.
**Palabras clave:** Análisis exploratorio de datos, retail,
comportamiento del consumidor, patrones de compra.}
}
Por favor, cita este trabajo como:
Camacho Guzmán, Sharon, and Jaime Gutiérrez, Msc., PhD (Docente en
Ciencia de Datos). 2025. “Evidencia de Aprendizaje 1 - Análisis
Descriptivo.” March 16, 2025.