Tugas Visualisasi Data Analisis Penjualan LEGO
1. Eksplorasi Data Awal Tampilkan informasi umum dataset (jumlah data, kolom, tipe data). Lakukan pembersihan data sederhana jika diperlukan (null values, duplikat, dll).
#install.packages("dsbox")
library(dsbox)
data(lego_sales) # Memuat dataset lego_sales
names(lego_sales) # Menampilkan nama kolom
## [1] "first_name" "last_name" "age" "phone_number" "set_id"
## [6] "number" "theme" "subtheme" "year" "name"
## [11] "pieces" "us_price" "image_url" "quantity"
str(lego_sales) # Menampilkan struktur dataset (jumlah data, tipe)
## Classes 'spec_tbl_df', 'tbl_df', 'tbl' and 'data.frame': 620 obs. of 14 variables:
## $ first_name : chr "Kimberly" "Neel" "Neel" "Chelsea" ...
## $ last_name : chr "Beckstead" "Garvin" "Garvin" "Bouchard" ...
## $ age : num 24 35 35 41 41 41 19 19 37 37 ...
## $ phone_number: chr "216-555-2549" "819-555-3189" "819-555-3189" NA ...
## $ set_id : num 24701 25626 24665 24695 25626 ...
## $ number : chr "76062" "70595" "21031" "31048" ...
## $ theme : chr "DC Comics Super Heroes" "Ninjago" "Architecture" "Creator" ...
## $ subtheme : chr "Mighty Micros" "Rise of the Villains" NA NA ...
## $ year : num 2018 2018 2018 2018 2018 ...
## $ name : chr "Robin vs. Bane" "Ultra Stealth Raider" "Burj Khalifa" "Lakeside Lodge" ...
## $ pieces : num 77 1093 333 368 1093 ...
## $ us_price : num 9.99 119.99 39.99 29.99 119.99 ...
## $ image_url : chr "http://images.brickset.com/sets/images/76062-1.jpg" "http://images.brickset.com/sets/images/70595-1.jpg" "http://images.brickset.com/sets/images/21031-1.jpg" "http://images.brickset.com/sets/images/31048-1.jpg" ...
## $ quantity : num 1 1 1 1 1 1 1 3 1 2 ...
## - attr(*, "spec")=List of 3
## ..$ cols :List of 14
## .. ..$ first_name : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_character" "collector"
## .. ..$ last_name : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_character" "collector"
## .. ..$ age : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
## .. ..$ phone_number: list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_character" "collector"
## .. ..$ set_id : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
## .. ..$ number : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_character" "collector"
## .. ..$ theme : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_character" "collector"
## .. ..$ subtheme : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_character" "collector"
## .. ..$ year : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
## .. ..$ name : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_character" "collector"
## .. ..$ pieces : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
## .. ..$ us_price : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
## .. ..$ image_url : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_character" "collector"
## .. ..$ quantity : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
## ..$ default: list()
## .. ..- attr(*, "class")= chr [1:2] "collector_guess" "collector"
## ..$ skip : num 1
## ..- attr(*, "class")= chr "col_spec"
summary(lego_sales) # Menampilkan ringkasan statistik dataset
## 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
##
sum(is.na(lego_sales)) # Mengecek jumlah nilai null dalam dataset
## [1] 392
lego_sales <- lego_sales[!duplicated(lego_sales), ] # Menghapus data duplikat
2. Visualisasi Wajib Buat minimal 5 visualisasi dari kategori berikut:
10 Customer dengan Jumlah Transaksi terbanyak
library(ggplot2)
top_customers <- aggregate(quantity ~ first_name + last_name, data = lego_sales, sum)
top_customers <- top_customers[order(-top_customers$quantity), ][1:10, ]
ggplot(top_customers, aes(y = reorder(paste(first_name, last_name), quantity),
x = quantity,
fill = ifelse(quantity == max(quantity), "Tertinggi", "Lainnya"))) +
geom_bar(stat = "identity") +
scale_fill_manual(values = c("Tertinggi" = "green", "Lainnya" = "grey")) +
labs(title = "10 Customer dengan Jumlah Transaksi Terbanyak",
y = "Customer", x = "Jumlah Transaksi") +
scale_x_continuous(breaks = seq(0, max(top_customers$quantity), by = 2)) +
theme_minimal() +
theme(legend.position = "none")
10 Tema LEGO Terpopuler Berdasarkan
Penjualan
top_themes <- aggregate(quantity ~ theme, data = lego_sales, sum)
top_themes <- top_themes[order(-top_themes$quantity), ][1:10, ]
ggplot(top_themes, aes(y = reorder(theme, quantity), x = quantity)) +
geom_bar(stat = "identity", fill = ifelse(top_themes$quantity == max(top_themes$quantity), "green",
ifelse(top_themes$quantity == min(top_themes$quantity), "red", "gray"))) +
labs(title = "10 Tema LEGO Terpopuler Berdasarkan Penjualan", x = "Jumlah Penjualan", y = "Tema") +
theme_minimal() +
theme(axis.text.y = element_text(angle = 0, hjust = 1))
Sebaran Jumlah Pieces dan Harga
ggplot(lego_sales, aes(x = pieces, y = us_price)) +
geom_point(alpha = 0.3, color = "orange", size = 2) +
geom_smooth(method = "lm", se = FALSE, color = "darkblue", linetype = "solid") +
labs(title = "Sebaran Jumlah Pieces dan Harga LEGO Set",
x = "Jumlah Pieces", y = "Harga (USD)") +
theme_minimal()
Komposisi Penjualan Berdasarkan Usia
library(dplyr)
lego_sales %>%
mutate(age_group = cut(age,
breaks = seq(0, 70, by = 5),
labels = c("0–5", "6–10", "11–15", "16–20", "21–25", "26–30", "31–35",
"36–40", "41–45", "46–50", "51–55", "56–60", "61–65", "66–70"),
right = FALSE)) %>%
group_by(age_group) %>%
summarise(total_quantity = sum(quantity)) %>%
mutate(warna = case_when(
total_quantity == max(total_quantity) ~ "Tertinggi",
total_quantity == min(total_quantity) ~ "Terendah",
TRUE ~ "Biasa"
)) %>%
ggplot(aes(x = age_group, y = total_quantity, fill = warna)) +
geom_col() +
geom_text(aes(label = total_quantity), vjust = -0.3, size = 3) +
scale_fill_manual(values = c("Tertinggi" = "green", "Terendah" = "red", "Biasa" = "grey")) +
labs(title = "Total Barang Terjual Berdasarkan Kelompok Usia",
x = "Kelompok Usia", y = "Jumlah Barang Terjual") +
theme_minimal() +
theme(legend.position = "none")
Heatmap Korelasi Antar Variabel Numerik
library(tidyr)
library(reshape2)
library(ggplot2)
library(ggcorrplot)
data <- na.omit(dsbox::lego_sales[, c("pieces", "us_price", "quantity")])
cor_matrix <- cor(data)
melted_cor <- melt(cor_matrix)
ggplot(melted_cor, aes(Var1, Var2, fill = value)) +
geom_tile(color = "white") +
geom_text(aes(label = round(value, 2)), size = 5) +
scale_fill_gradient2(low = "blue", high = "grey", mid = "white",
midpoint = 0, limit = c(-1, 1)) +
labs(title = "Heatmap Korelasi Antar Variabel Numerik") +
theme_minimal() +
coord_fixed() +
theme(
axis.text.x = element_text(angle = 0, vjust = 1, hjust = 1),
plot.title = element_text(hjust = 0.5, size = 16, face = "bold"),
legend.position = "none",
axis.text = element_text(size = 12),
axis.title = element_blank()
)
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?
-Dominasi tema-tema populer dalam penjualan LEGO
Visualisasi tema LEGO terpopuler menunjukkan bahwa tema seperti Star
Wars, Nexo Knights, dan Mixels menempati posisi teratas dalam jumlah
penjualan. Star Wars mendominasi dengan margin signifikan, yang
menunjukkan pengaruh kuat dari franchise besar terhadap daya tarik
konsumen. Tema-tema ini kemungkinan mendapat dukungan dari media populer
seperti film dan serial, yang memperluas jangkauan pasar LEGO dan
menarik penggemar lintas usia.
-Jumlah pieces dan harga LEGO memiliki hubungan yang sangat
kuat
Scatter plot dan heatmap korelasi memperlihatkan bahwa terdapat korelasi
positif yang sangat kuat antara jumlah pieces dan harga set LEGO (nilai
korelasi 0.94). Ini menunjukkan bahwa semakin kompleks dan besar sebuah
set (diukur dari banyaknya pieces), semakin mahal pula harganya. Hal ini
mengindikasikan bahwa ukuran dan kompleksitas menjadi faktor utama dalam
penentuan harga produk LEGO.
-Preferensi produk tidak dipengaruhi secara langsung oleh usia
Heatmap korelasi antar variabel numerik menunjukkan bahwa variabel usia
(diwakili oleh quantity sebagai indikator pembelian) tidak memiliki
korelasi yang signifikan terhadap harga ataupun jumlah pieces. Artinya,
tidak ada kecenderungan kelompok usia tertentu lebih memilih set yang
lebih mahal atau kompleks. Ini menunjukkan bahwa LEGO adalah produk yang
disukai lintas usia, baik anak-anak maupun dewasa.
-Kelompok usia 36–40 tahun menjadi pembeli terbesar
Grafik penjualan berdasarkan kelompok usia menunjukkan bahwa kelompok
usia 36–40 tahun merupakan pembeli terbanyak, disusul kelompok 21–25 dan
31–35 tahun. Hal ini membuktikan bahwa LEGO bukan hanya mainan
anak-anak, tapi juga menarik bagi kalangan dewasa muda hingga dewasa
mapan, baik untuk koleksi, hobi, maupun nostalgia. Ini membuka peluang
strategi pemasaran yang lebih menyasar segmen dewasa.
-Segelintir pelanggan mendominasi transaksi
Dari grafik 10 pelanggan dengan jumlah transaksi terbanyak, terlihat
bahwa satu pelanggan (Jackson Dominguez) memiliki jumlah transaksi yang
jauh lebih tinggi dibanding yang lain. Ini mengindikasikan adanya
ketimpangan atau distribusi tidak merata, di mana sebagian besar
penjualan disumbang oleh pelanggan loyal tertentu. Strategi retensi
seperti loyalty program bisa dimanfaatkan untuk mempertahankan pelanggan
dengan kontribusi tinggi ini.