Análisis de comercio minorista en grandes conjuntos de datos.

El conjunto de datos representa datos transaccionales minoristas. Contiene información sobre los clientes, sus compras, productos y detalles de las transacciones.

Descripcion de las variables

State Estado de los clientes Country Pais de los clientes
Age=Edad de los clientes Gender=Genero de los clientes
Income=Nivel de ingresos de los clientes Date=Fecha en formato YYYY-MM-DD Year=Año Month=Mes Total_Purchases=Total de compras Amount Total_Amount=Monto total de ventas
Product_Category=Categoria de los productos Product_Brand=Marca de productos Product_Type=Tipo de productos Feedback=Reseñas de los clientes Ratings products=Calificaciones de los productos

Carga de librerias

Caego todas las librerias que voy a utilizar para que mis comandos corran bien las funciones.

library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.1.4     ✔ readr     2.1.5
## ✔ forcats   1.0.0     ✔ stringr   1.5.1
## ✔ ggplot2   3.5.1     ✔ tibble    3.2.1
## ✔ lubridate 1.9.3     ✔ tidyr     1.3.1
## ✔ purrr     1.0.2     
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(tidyr)
library(rmarkdown)
library(ggplot2)
library(dplyr)
library(maps)
## Warning: package 'maps' was built under R version 4.4.1
## 
## Adjuntando el paquete: 'maps'
## 
## The following object is masked from 'package:purrr':
## 
##     map
library(scales)
## 
## Adjuntando el paquete: 'scales'
## 
## The following object is masked from 'package:purrr':
## 
##     discard
## 
## The following object is masked from 'package:readr':
## 
##     col_factor
library(sf)
## Warning: package 'sf' was built under R version 4.4.1
## Linking to GEOS 3.12.1, GDAL 3.8.4, PROJ 9.3.1; sf_use_s2() is TRUE

Carga de la base de datos

Primero se carga la base de datos con la que vamos a trabajar para proceder con la limpieza de la misma.

base<- read.csv('/Users/danna/OneDrive/Documentos/DannaR/new_retail_data.csv')

Limpieza de datos.

A continuacion se hara una limpieza de la base, dejando los elementos y columnas que vamos a utilizar para el analisis. Al final de mi base habia demasiadas filas con NA y espacios en blanco, asi que primero hago que los espacios en blanco sean NA, y por ultimo borro todos los NA para que mi base quede solo con los elementos que vamos a utilizar. Tambien cambie el orden de unas columnas solo para que me fuera mas facil identificar las principales variables.

base<- base %>% select(-Transaction_ID,-Customer_ID,-Name,-Email,-Phone,-Address,-Zipcode,-Time,-City)
base[base == ""] <- NA
base<- drop_na(base)
base<- base %>% select(Income, everything())
base<- base %>% select(Age, everything())
base<- base %>% select(Gender, everything())
base<- base %>% select(Month, everything())
base<- base %>% select(Year, everything())

Distribucion de transacciones por pais

• A continuación, estoy creando una tabla de frecuencias convirtiéndola a un data frame, con la función colnames les asigno un nombre nuevo a las columnas, y con la función order las acomodo en orden descendente. • Para hacer el grafico AES: para definir las variables, quedando en el eje de las X los países y la frecuencia de transacciones en el eje Y. geom_bar: creo el grafico de barras con las alturas determinadas por los valores de la frecuencia. Labs: agrego las etiquetas y titulo que quiero en el grafico scale_fill_manual: asigna colores específicos a los países. Theme: personalicé la apariencia del gráfico, el texto y la posición.

country_freq <- as.data.frame(table(base$Country))
colnames(country_freq) <- c("Country", "Frequency")
country_freq <- country_freq[order(-country_freq$Frequency),]
print(country_freq)
##     Country Frequency
## 5       USA     52381
## 4        UK     35107
## 3   Germany     25447
## 1 Australia     17832
## 2    Canada     17744
ggplot(country_freq, aes(x = reorder(Country, -Frequency), y = Frequency, fill = Country)) +
  geom_bar(stat = "identity", show.legend = FALSE) +
  labs(title = "Distribución de transacciones por país",
       x = "País",
       y = "Frecuencia") +
  scale_fill_manual(values = c("red", "blue", "green", "purple", "orange")) +
  theme(axis.text.x = element_text(angle = 45, hjust = 1, vjust = 1),
        plot.title = element_text(face = 'bold'))

A continuacion se muestra como se distribuyen las transacciones entre diferentes paises, ayudando a indentificar patrones de compra segun la ubicacion geografica de los clientes.

Distribucion de transacciones por genero

Cree una tabla de la variable “Genero” de la base y la convierto a un dataframe, en la que esta la variable genero y la frecuencia del mismo. A continuacion hago una grafica de pastel para representar el resultado.

gender_freq <- as.data.frame(table(base$Gender))
colnames(gender_freq) <- c("Gender", "Frequency")
gender_freq <- gender_freq[order(-gender_freq$Frequency),]
print(gender_freq)
##   Gender Frequency
## 2   Male     95537
## 1 Female     52974
ggplot(base, aes(x = "", fill = Gender)) +
  geom_bar(width = 1) +
  coord_polar(theta = "y") +
  labs(title = "Distribución de transacciones por género",
       fill = "Género") +
  scale_fill_manual(values = c("blue", "pink")) +
  theme_void() +
  theme(legend.position = "right")

Este grafico de pastel muestra la distribucion de transacciones entre hombres y mujeres, facilitando la visualizacion de como se distribuyen las comoras segun el genero de los clientes.

Cantidad total distribuida por grupo de ingreso

Se creo un nuevo data frame de la variable de ingreso agregando el monto total, la cual se modifico a porcentajes dependiendo del nivel de ingresos. Al final hicfe un grafico de

df_agrupado <- base %>%
  group_by(Income) %>%
  summarise(Total_Amount = sum(Total_Amount))
df_agrupado <- df_agrupado %>%
  mutate(Percentage = Total_Amount / sum(Total_Amount))
print(df_agrupado)
## # A tibble: 3 × 3
##   Income Total_Amount Percentage
##   <chr>         <dbl>      <dbl>
## 1 High      50868701.      0.250
## 2 Low       60210556.      0.296
## 3 Medium    92354576.      0.454
ggplot(df_agrupado, aes(x = "", y = Total_Amount, fill = Income)) +
  geom_bar(stat = "identity", width = 1) +
  coord_polar(theta = "y") +
  geom_text(aes(label = scales::percent(Percentage, accuracy = 0.1)), position = position_stack(vjust = 0.5)) +
  scale_fill_manual(values=c("yellow","orange","red")) +
  labs(title = "Cantidad total distribuida por grupo de ingreso") +
  theme_void() +
  theme(plot.title = element_text(hjust = 0.5, face = "bold"))

El grafico de pastel muestra la distribucion del monto total por grupo de ingresos. Cada segmento del pastel muestra un grupo de ingresos diferente, y su tamaño es proporcional al porcentaje de lo que gasta cada uno de ellos. Esto nos permite interpretar la distribucion de los ingresos y que tanto se permiten gastar las personas en compras.

Top 10 de marcas de productos mas vendidas

Cree un dataframe donde agrupe por marca de producto y agrego una nuevo variable del total de compras por marca, con la funcion arrange ordeno las marcas en orden descendente segun la suma total de compras, slecciono las primeras 10 marcas resultantes y hago un grafico de barras

df_brand_purchases <- base %>%
  group_by(Product_Brand) %>%
  summarise(Total_Purchases = sum(Total_Purchases)) %>%
  arrange(desc(Total_Purchases)) %>%
  slice(1:10)
print(df_brand_purchases)
## # A tibble: 10 × 2
##    Product_Brand     Total_Purchases
##    <chr>                       <int>
##  1 Pepsi                      110907
##  2 Samsung                     46817
##  3 Sony                        46648
##  4 Coca-Cola                   46645
##  5 Random House                46526
##  6 Nike                        46420
##  7 Nestle                      46416
##  8 HarperCollins               46303
##  9 Bed Bath & Beyond           46160
## 10 Home Depot                  46139
ggplot(df_brand_purchases, aes(x = reorder(Product_Brand, Total_Purchases), y = Total_Purchases, fill = Product_Brand)) +
  geom_bar(stat = "identity") +
  coord_flip() +
  labs(title = "Top 10 de Marcas mas vendidas", x = "Marca", y = "Total de Compras") +
  theme_minimal() +
  theme(plot.title = element_text(hjust = 0.5, face = "bold"),
        legend.position = "none")

El grafico muestra las 10 marcas principales con mas ventas ordenadas de mayor a menor, aunque se observa que estan entre las 14,000 a 14,700 ventas, esto nos permite visualizar cuales son las marcas mas populares entre los compradores.

Monto total de ventas por mes

Con la funcion factor y levels convierto la variable en un factor para especificar los niveles que seran definidos en mi vector_order. Con order=TRUE indico que el valor esta ordenado. Agrupo mi base por la columna “month” y calculando la suma de la columna del monto total por cada mes, cuento cuantas veces aparece cada mes y lo guardo en una nueva columna, para hacer por ultimo el grafico

month_order <- c("January","February","March","April","May","June","July","August","September","October","November","December")
base$Month <- factor(base$Month, levels = month_order, ordered = TRUE)
month_amount_sum <- base %>% group_by(Month) %>%
  summarise(Total_Amount = sum(Total_Amount))
month_count <- base %>% count(Month) %>% rename(Count=n)
month_summary<- month_amount_sum %>% left_join(month_count,by="Month")
print(month_summary)
## # A tibble: 12 × 3
##    Month     Total_Amount Count
##    <ord>            <dbl> <int>
##  1 January      39026740. 28625
##  2 February     14557707. 10645
##  3 March        15366652. 11096
##  4 April        14881680. 10716
##  5 May          15019941. 10944
##  6 June         14653462. 10823
##  7 July         15115087. 11076
##  8 August       15196546. 10919
##  9 September    14601130. 10714
## 10 October      15226122. 11156
## 11 November     14608168. 10728
## 12 December     15180596. 11069
ggplot(data = month_summary, aes(x = Month)) +
  geom_bar(aes(y = Total_Amount), stat = "identity", fill = "blue", alpha = 0.6) +
  geom_line(aes(y = Count * max(Total_Amount) / max(Count)), group = 1, color = "red", size = 1) +
  geom_point(aes(y = Count * max(Total_Amount) / max(Count)), color = "red", size = 2) +
  scale_y_continuous(
    name = "Monto Total",
    sec.axis = sec_axis(~ . * max(month_count$Count) / max(month_amount_sum$Total_Amount), name = "Conteo de Ventas")
  ) +
  labs(title = "Monto Total y Conteo de Ventas por Mes", x = "Mes") +
  theme_minimal() +
  theme(plot.title = element_text(hjust = 0.5, face = "bold"))
## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## ℹ Please use `linewidth` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.

Como se observa en el grafico las barras azules representran el total de ventas por cada mes, mientras que la linea de tendencia roja muestra el numero de registros de las ventas. En el mes de Enero se muestra un aumento considerablen mientras que los demas meses del año se mantiene casi constante, ya que hay poca diferencia entre uno y otro.

¿De qué país los minoristas generan más ganancias?

Para este paso creo un df agrupado por paises y agrego la suma del monto total por cada uno, agregando una nueva columna el monto total por porcentaje y utilizo un filtro para el pais que genera mas ganancias y hago mi grafico circular.

country_amount<- base %>% group_by(Country) %>% summarise(Total_Amount= sum(Total_Amount))
country_amount<- country_amount %>% mutate(Percentage=Total_Amount/sum(Total_Amount)*100)
top_country<- country_amount %>% filter(Total_Amount==max(Total_Amount))
print(top_country)
## # A tibble: 1 × 3
##   Country Total_Amount Percentage
##   <chr>          <dbl>      <dbl>
## 1 USA        71466289.       35.1
ggplot(country_amount, aes(x = 2, y = Total_Amount, fill = Country)) +
  geom_bar(stat = "identity", width = 1) +
  coord_polar(theta = "y") +
  geom_text(aes(label = paste0(round(Percentage, 1), "%")), position = position_stack(vjust = 0.5)) +
  annotate("text", x = 0, y = 0, label = paste(top_country$Country, "\n", "$", formatC(top_country$Total_Amount, format = "f", big.mark = ",")), size = 6) +
  labs(title = "Distribución del Monto Total por País") +
  theme_void() +
  theme(legend.position = "right", plot.title = element_text(hjust = 0.5, face = "bold"))

El gráfico de dona muestra la distribución del monto total por país. Cada segmento de la dona representa un país y su tamaño es proporcional al porcentaje del monto total que corresponde a ese país. Como anteriormente vimos en la grafica de barras Reino Unido es el pais con masyores transacciones y asi mismo es el que mas genera ganancias.

Estado con mas ventas en Estados Unidos

Primero cargo un mapa de los Estados Unidos, filtro la base y agrupo por año y estado en un nuevo data frame, calculo el monto total y la marca mas frecuente por cada año y estado, despues sumo los montos totales y cuento la frecuencia de las marcas para despues seleccionar la mas frecuente y graficar.

us_states<- st_as_sf(map("state",plot = FALSE,fill = TRUE))
us_data <- base %>% filter(Country == "USA") %>%
  group_by(Year, State) %>%
  summarise(Total_Amount = sum(Total_Amount, na.rm = TRUE),
            Top_Brand = names(sort(table(Product_Brand), decreasing = TRUE)[1]))
## `summarise()` has grouped output by 'Year'. You can override using the
## `.groups` argument.
top_sales_state <- us_data %>%
  group_by(Year) %>%
  top_n(1, Total_Amount)
top_brand <- names(sort(table(base$Product_Brand), decreasing = TRUE)[1])
print(top_brand)
## [1] "Pepsi"
ggplot(data = us_states) +
  geom_sf(fill = "white", color = "black") +
  geom_sf(data = us_states %>% filter(ID == "connecticut"), fill = "red", color = "black") +
  theme_minimal() +
  labs(title = "Estado con más ventas en Estados Unidos",
       subtitle = paste("Marca más vendida:", top_brand),
       fill = "Ventas") +
  theme(plot.title = element_text(hjust = 0.5),
        plot.subtitle = element_text(hjust = 0.5))

En este mapa se muestra que en el estado de Connecticut se producen mayormente las ventas de Pepsi en todo el pais de Estados Unidos de 2023 a 2024.

Marca con mejor y peor reseña

Para obtener la marca con peor y mejor reseña filtre la base por los datos de USA y los agrupo por años y estado, calculo el monto total y la marca mas frecuente por cada año y estado, sumo los montos totales y conte las frecuencias de las marcas, por utilo selecciono la mas frecuente y grafico.

top_feedback_brands <- base %>%
  filter(Feedback %in% c("Excellent", "Bad")) %>%
  group_by(Feedback, Product_Brand) %>%  summarize(Count = n()) %>%
  slice(which.max(Count)) %>%
  ungroup()
## `summarise()` has grouped output by 'Feedback'. You can override using the
## `.groups` argument.
print(top_feedback_brands)
## # A tibble: 2 × 3
##   Feedback  Product_Brand Count
##   <chr>     <chr>         <int>
## 1 Bad       Adidas         1563
## 2 Excellent HarperCollins  3273
ggplot(top_feedback_brands, aes(x = "", y = Product_Brand, fill = Feedback)) +
  geom_bar(width = 1, stat = "identity") +
  coord_polar(theta = "y") +
  facet_wrap(~ Product_Brand) +
  theme_minimal() +
  labs(title = "Marcas con mejor y peor reseña",
       fill = "Feedback")

Como se observa en el grafico la marca con mejores reseñas de “Excelente” es Harper Collins y la marca con mas reseñas de “Malo es Adidas. Esto nos ayuda a analizar la satisfaccion y preferencias del cliente a la hora de comprar.

Conclusion

Como conclusion en esta base de datos con la que estuve trabajando pude analizar que en base a las dustribuciones por transacciones la mayoria de las compras son echas por mujeres, ademas Estados Unidos tiene el mayor numero de transacciones echas y en el que se generan mas ganancias para los minoristas, especialmente en el estado de Connescticut a pesar que es uno de los estados mas pequeños del pais, en lo que podemos observar Pepsi es la marca mas vendida aunque, Harper Collins se lleva la mejor reseña con mas “Excelemt” que cualquier otra marca, a diferencia de Adidas que tiene el peor numero de reseñas malas, con esto se puede deducir las preferencias de los consumidores, por ultimo la temporada en que mas se registraron el total de ventas en ambos años, fue en Enero.