No 1 Eksplorasi Data Awal

Tampilkan informasi umum dataset (jumlah data, kolom, tipe data). Lakukan pembersihan data sederhana jika diperlukan (null values, duplikat, dll).

library(dsbox)
library(tidyverse)
library(ggplot2)
library(ggthemes)
library(scales)
library(ggcorrplot)
data <- lego_sales
glimpse(data)
## Rows: 620
## Columns: 14
## $ first_name   <chr> "Kimberly", "Neel", "Neel", "Chelsea", "Chelsea", "Chelse…
## $ last_name    <chr> "Beckstead", "Garvin", "Garvin", "Bouchard", "Bouchard", …
## $ age          <dbl> 24, 35, 35, 41, 41, 41, 19, 19, 37, 37, 19, 19, 20, 36, 3…
## $ phone_number <chr> "216-555-2549", "819-555-3189", "819-555-3189", NA, NA, N…
## $ set_id       <dbl> 24701, 25626, 24665, 24695, 25626, 24721, 24797, 24701, 2…
## $ number       <chr> "76062", "70595", "21031", "31048", "70595", "10831", "75…
## $ theme        <chr> "DC Comics Super Heroes", "Ninjago", "Architecture", "Cre…
## $ subtheme     <chr> "Mighty Micros", "Rise of the Villains", NA, NA, "Rise of…
## $ year         <dbl> 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 201…
## $ name         <chr> "Robin vs. Bane", "Ultra Stealth Raider", "Burj Khalifa",…
## $ pieces       <dbl> 77, 1093, 333, 368, 1093, 19, 233, 77, 108, NA, 13, 15, 6…
## $ us_price     <dbl> 9.99, 119.99, 39.99, 29.99, 119.99, 9.99, 24.99, 9.99, 9.…
## $ image_url    <chr> "http://images.brickset.com/sets/images/76062-1.jpg", "ht…
## $ quantity     <dbl> 1, 1, 1, 1, 1, 1, 1, 3, 1, 2, 1, 1, 2, 1, 1, 1, 1, 1, 1, …
summary(data)
##   first_name         last_name              age        phone_number      
##  Length:620         Length:620         Min.   :16.00   Length:620        
##  Class :character   Class :character   1st Qu.:25.00   Class :character  
##  Mode  :character   Mode  :character   Median :33.00   Mode  :character  
##                                        Mean   :34.36                     
##                                        3rd Qu.:41.00                     
##                                        Max.   :68.00                     
##                                                                          
##      set_id         number             theme             subtheme        
##  Min.   :24548   Length:620         Length:620         Length:620        
##  1st Qu.:24725   Class :character   Class :character   Class :character  
##  Median :24805   Mode  :character   Mode  :character   Mode  :character  
##  Mean   :25125                                                           
##  3rd Qu.:25640                                                           
##  Max.   :26060                                                           
##                                                                          
##       year          name               pieces          us_price     
##  Min.   :2018   Length:620         Min.   :  13.0   Min.   :  3.99  
##  1st Qu.:2018   Class :character   1st Qu.:  70.0   1st Qu.:  9.99  
##  Median :2018   Mode  :character   Median : 114.0   Median : 19.99  
##  Mean   :2018                      Mean   : 254.2   Mean   : 29.04  
##  3rd Qu.:2018                      3rd Qu.: 313.0   3rd Qu.: 29.99  
##  Max.   :2018                      Max.   :4634.0   Max.   :349.99  
##                                    NA's   :69                       
##   image_url            quantity    
##  Length:620         Min.   :1.000  
##  Class :character   1st Qu.:1.000  
##  Mode  :character   Median :1.000  
##                     Mean   :1.437  
##                     3rd Qu.:2.000  
##                     Max.   :5.000  
## 
nrow(data)  
## [1] 620
ncol(data)  
## [1] 14
colnames(data)
##  [1] "first_name"   "last_name"    "age"          "phone_number" "set_id"      
##  [6] "number"       "theme"        "subtheme"     "year"         "name"        
## [11] "pieces"       "us_price"     "image_url"    "quantity"
colSums(is.na(data))
##   first_name    last_name          age phone_number       set_id       number 
##            0            0            0           92            0            0 
##        theme     subtheme         year         name       pieces     us_price 
##            0          172            0            0           69            0 
##    image_url     quantity 
##           59            0
sum(duplicated(data))
## [1] 0
data_clean <- data %>%
  drop_na() %>%
  distinct()
dim(data_clean)
## [1] 287  14

No 2 Visualisasi Wajib Buat minimal 5 visualisasi dari kategori berikut:

  1. 10 Customer dengan Jumlah Transaksi Terbanyak
library(ggplot2)
library(dplyr)
top_customers <- data %>%
  group_by(first_name, last_name) %>%
  summarise(total_transactions = sum(quantity), .groups = 'drop') %>%
  arrange(desc(total_transactions)) %>%
  head(10)
top_customers$full_name <- paste(top_customers$first_name, top_customers$last_name)
ggplot(top_customers, aes(x = reorder(full_name, total_transactions), y = total_transactions)) +
  geom_bar(stat = "identity", fill = "steelblue") +
  coord_flip() +
  labs(title = "10 Customer dengan Jumlah Transaksi Terbanyak",
       x = "Customer",
       y = "Total Transaksi") +
  theme_minimal()

b. 10 Tema LEGO Terpopuler Berdasarkan Penjualan

library(dplyr)
library(ggplot2)
top_themes <- data %>%
  group_by(theme) %>%
  summarise(total_sales = sum(us_price * quantity, na.rm = TRUE), .groups = 'drop') %>%
  arrange(desc(total_sales)) %>%
  head(10)
ggplot(top_themes, aes(x = reorder(theme, total_sales), y = total_sales)) +
  geom_bar(stat = "identity", fill = "#228B22") +
  coord_flip() +
  labs(title = "10 Tema LEGO Terpopuler Berdasarkan Penjualan",
       x = "Tema LEGO",
       y = "Total Penjualan (USD)") +
  theme_minimal()

  1. Sebaran Jumlah Pieces dan Harga
ggplot(data, aes(x = pieces, y = us_price)) +
  geom_point(alpha = 0.7, color = "dodgerblue", size = 3) +
  geom_smooth(method = "lm", se = FALSE, color = "darkred", linetype = "solid") +
  coord_cartesian(xlim = c(0, 2000), ylim = c(0, 150)) +
  labs(
    title = "Hubungan Jumlah Pieces dan Harga LEGO Set",
    x = "Jumlah Pieces",
    y = "Harga (USD)"
  ) +
  theme_light() +
  theme(
    plot.title = element_text(hjust = 0.5, face = "bold", size = 16),
    plot.subtitle = element_text(hjust = 0.5, size = 12)
  )

  1. Komposisi Penjualan Berdasarkan Usia
data <- data %>%
  mutate(age_group = cut(age,
                         breaks = seq(0, 70, by = 10),
                         labels = c("0–9", "10–19", "20–29", "30–39", "40–49", "50–59", "60–69"),
                         right = FALSE))

age_sales <- data %>%
  group_by(age_group) %>%
  summarise(total_sales = sum(quantity)) %>%
  arrange(desc(total_sales))

ggplot(age_sales, aes(x = reorder(age_group, total_sales), y = total_sales)) +
  geom_col(fill = "lightcoral", color = "lightcoral", size = 1.2) +
  coord_flip() +
  geom_text(aes(label = total_sales), hjust = 1.1, size = 4, color = "black") +
  labs(title = "Komposisi Penjualan Berdasarkan Kelompok Usia",
       subtitle = "Total penjualan berdasarkan kelompok usia",
       x = "Kelompok Usia", y = "Jumlah Terjual") +
  theme_minimal() +
  theme(
    plot.title = element_text(hjust = 0.5, face = "bold", size = 16),
    plot.subtitle = element_text(hjust = 0.5, size = 12),
    axis.title = element_text(size = 12),
    axis.text = element_text(size = 10)
  )

  1. Heatmap Korelasi Antar Variabel Numerik
numeric_vars <- data %>%
  select(age, pieces, us_price, quantity) %>%
  drop_na()

cor_matrix <- cor(numeric_vars)

ggcorrplot(cor_matrix, 
           lab = TRUE,           
           type = "lower",      
           colors = c("blue", "white", "red"),  
           lab_size = 4,         
           title = "Korelasi Antar Variabel Numerik") +
  theme_minimal() +       
  theme(
    plot.title = element_text(hjust = 0.5, size = 16, face = "bold"),  
    axis.title = element_text(size = 12),                            
    axis.text = element_text(size = 10)                                
  )

No 3 Insight dan Narasi

Tuliskan 3–5 insight menarik dari visualisasi yang dibuat.Contoh: Apakah tema tertentu mendominasi revenue? Apakah set dengan lebih banyak pieces selalu lebih mahal? Apakah ada preferensi tema LEGO pada kelompok usia tertentu?

  1. Tema Tertentu Mendominasi Total Revenue Dari grafik “10 Tema LEGO Terpopuler Berdasarkan Penjualan”, terlihat bahwa hanya beberapa tema saja yang menyumbang sebagian besar pendapatan. Hal ini menunjukkan adanya dominasi tema tertentu yang lebih digemari pasar, kemungkinan karena lisensi populer (misalnya tema superhero, film, atau franchise terkenal).

  2. Pelanggan Tertentu Melakukan Pembelian dalam Jumlah Sangat Besar Dari grafik “10 Customer dengan Jumlah Transaksi Terbanyak”, terlihat bahwa terdapat beberapa pelanggan yang secara signifikan lebih aktif dalam berbelanja LEGO. Hal ini dapat dimanfaatkan untuk strategi pemasaran, seperti menawarkan promo atau program membership khusus bagi pelanggan yang membeli dalam jumlah besar.

  3. Harga LEGO Naik Seiring Jumlah Pieces, Tapi Tidak Berdampak Pada Volume Pembelian Terdapat hubungan yang kuat antara harga (us_price) dan jumlah kepingan (pieces), namun korelasinya dengan quantity sangat rendah. Artinya, meskipun harga meningkat karena jumlah pieces lebih banyak, pembeli tetap tertarik dan hal ini tidak mengurangi minat beli mereka.

  4. Jumlah Penjualan (Quantity) Tidak Terpengaruh Oleh Harga atau Ukuran Korelasi antara quantity dengan us_price dan pieces sangat rendah (hampir nol), menandakan bahwa harga tinggi atau jumlah pieces besar tidak menghambat penjualan. Ini membuka kemungkinan bahwa faktor lain seperti tema atau preferensi pelanggan lebih menentukan keputusan pembelian.

  5. Kelompok Usia 20–29 Tahun Menyumbang Penjualan Terbanyak Visualisasi penjualan berdasarkan kelompok usia menunjukkan bahwa kelompok usia 20–29 mendominasi dalam jumlah pembelian. Hal ini menandakan bahwa LEGO tidak hanya dimainkan oleh anak-anak, tapi juga dibeli oleh remaja dan dewasa muda sebagai koleksi, hobi, atau hadiah.