#1: Eksplorasi Data Awal
# Menampilkan struktur dan ringkasan data
str(lego_sales)
## 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)
## 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
##
# Pembersihan data sederhana
# Mengecek missing values
sum(is.na(lego_sales))
## [1] 392
# Menghapus baris dengan missing values
lego_sales <- na.omit(lego_sales)
# Mengecek duplikat
sum(duplicated(lego_sales))
## [1] 0
#2: Visualisasi Data
#1. 10 Customer dengan Jumlah Transaksi Terbanyak (Menggunakan Diagram Pie yang Bersih dan Jelas)
library(dplyr)
##
## Attaching package: '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)
top_customers <- lego_sales %>%
group_by(first_name, last_name) %>%
summarise(Total_Transactions = n(), .groups = "drop") %>%
arrange(desc(Total_Transactions)) %>%
head(10) %>%
mutate(Full_Name = paste(first_name, last_name))
# Membuat pie chart yang bersih
ggplot(top_customers, aes(x = "", y = Total_Transactions, fill = Full_Name)) +
geom_bar(stat = "identity", width = 1) +
coord_polar(theta = "y") +
labs(title = "10 Customer dengan Jumlah Transaksi Terbanyak",
subtitle = "Pelanggan dengan jumlah transaksi terbanyak di dataset LEGO Sales",
caption = "Data: LEGO Sales") +
theme_void() + # Menghilangkan background untuk tampilan lebih bersih
scale_fill_manual(values = c("#FFB6C1", "#FF69B4", "#FF1493", "#FF6347", "#FF7F50",
"#FF4500", "#FFD700", "#ADFF2F", "#98FB98", "#E0FFFF")) + # Warna cerah yang lembut
theme(plot.title = element_text(size = 16, face = "bold"),
plot.subtitle = element_text(size = 12),
plot.caption = element_text(size = 10, face = "italic")) # Menambahkan style yang bersih dan jelas
#2. 10 Tema LEGO Terpopuler Berdasarkan Penjualan (Menggunakan Diagram Dot yang Lebih Jelas)
top_themes <- lego_sales %>%
group_by(theme) %>%
summarise(Total_Sales = sum(quantity, na.rm = TRUE), .groups = 'drop') %>%
arrange(desc(Total_Sales)) %>%
head(10)
# Membuat diagram dot dengan desain yang bersih
ggplot(top_themes, aes(x = reorder(theme, -Total_Sales), y = Total_Sales)) +
geom_point(size = 4, color = "#FFB6C1") + # Titik dengan warna cerah dan lembut
coord_flip() +
labs(title = "10 Tema LEGO Terpopuler Berdasarkan Penjualan",
subtitle = "Penjualan berdasarkan tema LEGO yang paling laris",
x = "Tema LEGO",
y = "Total Penjualan") +
theme_minimal(base_size = 14) + # Menggunakan tema minimal yang lebih bersih
theme(plot.title = element_text(size = 16, face = "bold"),
plot.subtitle = element_text(size = 12),
axis.text.x = element_text(size = 12),
axis.text.y = element_text(size = 12)) # Memastikan teks mudah dibaca
#3. Sebaran Jumlah Pieces dan Harga (Menggunakan Diagram Bubble yang Bersih)
ggplot(lego_sales, aes(x = pieces, y = us_price, size = quantity)) + # Menambahkan size berdasarkan quantity
geom_point(alpha = 0.6, color = "#ADD8E6") + # Warna titik cerah dan lembut
geom_smooth(method = "lm", se = FALSE, color = "#FF6347") + # Garis dengan warna kontras
labs(
title = "Sebaran Jumlah Pieces dan Harga",
subtitle = "Hubungan antara jumlah pieces dan harga LEGO berdasarkan dataset",
x = "Jumlah Pieces",
y = "Harga (USD)",
caption = "Data: LEGO Sales"
) +
theme_minimal(base_size = 14) + # Menggunakan tema minimal untuk desain bersih
theme(plot.title = element_text(size = 16, face = "bold"),
plot.subtitle = element_text(size = 12),
plot.caption = element_text(size = 10, face = "italic"))
## 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.
## `geom_smooth()` using formula = 'y ~ x'
## Warning: The following aesthetics were dropped during statistical transformation: size.
## ℹ This can happen when ggplot fails to infer the correct grouping structure in
## the data.
## ℹ Did you forget to specify a `group` aesthetic or to convert a numerical
## variable into a factor?
#4. Komposisi Penjualan Berdasarkan Usia (Menggunakan Diagram Stacked Bar yang Bersih)
sales_by_age <- lego_sales %>%
group_by(age) %>%
summarise(Total_Sales = sum(quantity), .groups = 'drop')
# Membuat diagram stacked bar dengan desain bersih
ggplot(sales_by_age, aes(x = factor(age), y = Total_Sales, fill = factor(age))) +
geom_bar(stat = "identity") +
labs(title = "Komposisi Penjualan Berdasarkan Usia",
subtitle = "Total penjualan berdasarkan usia pembeli LEGO",
x = "Usia Pembeli",
y = "Total Penjualan",
caption = "Data: LEGO Sales") +
theme_minimal(base_size = 14) + # Menggunakan tema minimal untuk tampilan bersih
theme(plot.title = element_text(size = 16, face = "bold"),
plot.subtitle = element_text(size = 12),
axis.text.x = element_text(size = 12, angle = 45, hjust = 1),
axis.text.y = element_text(size = 12)) # Menambahkan rotasi untuk teks yang lebih mudah dibaca
#5. Heatmap Korelasi Antar Variabel Numerik (Menggunakan Heatmap yang Lebih Bersih)
library(corrplot)
## corrplot 0.95 loaded
numeric_data <- lego_sales %>% select(pieces, us_price, quantity)
cor_matrix <- cor(numeric_data)
corrplot(cor_matrix, method = "color", type = "upper",
title = "Heatmap Korelasi Antar Variabel Numerik",
col = colorRampPalette(c("#FFB6C1", "#ADD8E6", "#98FB98"))(200), # Warna cerah namun lembut
tl.cex = 0.8, tl.col = "black", # Ukuran teks label dan warna
number.cex = 0.8) # Ukuran teks untuk angka di dalam heatmap
#3. Insight Menarik Berdasarkan Visualisasi
#jawab: 1. Preferensi Pelanggan terhadap Tema LEGO Tertentu
# Dari hasil visualisasi tema dengan penjualan tertinggi, terlihat jelas bahwa pelanggan memiliki ketertarikan yang kuat terhadap tema-tema tertentu, khususnya Star Wars, City, dan Friends. Ketiga tema ini menempati posisi puncak dari segi kuantitas pembelian. Hal ini mengindikasikan bahwa tema yang memiliki unsur naratif kuat, karakter ikonik, dan elemen yang familiar di kalangan anak-anak hingga dewasa mampu menciptakan daya tarik tersendiri. Dengan kata lain, LEGO tidak hanya menjual produk konstruksi, tetapi juga menjual cerita dan pengalaman bermain. Maka dari itu, perusahaan dapat mempertimbangkan untuk lebih banyak berinvestasi dalam pengembangan tema-tema ini, termasuk merilis seri lanjutan atau edisi spesial untuk menjaga ketertarikan pasar.
# 2. Kompleksitas Produk Tidak Selalu Mencerminkan Harga
# Analisis hubungan antara jumlah pieces dan harga menunjukkan adanya tren positif secara umum, yaitu semakin kompleks (banyak pieces), maka harganya pun meningkat. Akan tetapi, terdapat beberapa pengecualian yang menarik—terdapat set dengan jumlah pieces yang relatif sedikit, namun dibanderol dengan harga tinggi. Hal ini bisa dikarenakan produk tersebut memiliki lisensi eksklusif seperti karakter dari film blockbuster, desain arsitektur unik, atau diproduksi dalam jumlah terbatas. Temuan ini menunjukkan bahwa harga LEGO tidak hanya bergantung pada kuantitas material, tetapi juga pada aspek branding, kolektibilitas, dan persepsi nilai dari konsumen. Bagi tim pemasaran, ini bisa menjadi dasar dalam menyusun strategi promosi untuk produk premium yang menyasar segmen kolektor.
# 3. Peluang Optimasi Harga Berdasarkan Analisis Korelasi
# Melalui visualisasi heatmap korelasi, diperoleh pemahaman bahwa variabel "jumlah pieces" dan "harga" memiliki korelasi yang cukup kuat, menunjukkan keterkaitan logis antara ukuran set dan nilai jual. Namun, menariknya, korelasi antara harga dan jumlah unit yang terjual tidak sekuat itu, bahkan cenderung negatif. Ini menandakan bahwa semakin mahal suatu produk, kemungkinan besar volumenya lebih sedikit. Meski produk mahal bisa memberikan margin keuntungan yang besar, jumlah penjualannya yang rendah bisa membatasi total pendapatan. Maka, perusahaan perlu mengevaluasi kembali keseimbangan antara pricing strategy dan market reach—apakah lebih menguntungkan menjual sedikit produk mahal, atau banyak produk dengan harga terjangkau.
# 4. Distribusi Penjualan Berdasarkan Usia Menunjukkan Segmentasi Pasar yang Jelas
# Dalam analisis penjualan berdasarkan usia target produk, ditemukan bahwa rentang usia tertentu seperti 6+, 7+, dan 8+ menunjukkan angka penjualan tertinggi. Hal ini memberi gambaran bahwa kelompok usia ini merupakan segmen pasar yang paling aktif dan responsif terhadap produk LEGO. Di sisi lain, produk yang ditujukan untuk usia lebih tinggi (misalnya 12+ atau 16+) menunjukkan penjualan yang lebih rendah, kemungkinan karena tingkat kesulitan yang lebih tinggi atau harga yang lebih mahal. Insight ini dapat digunakan untuk mengarahkan pengembangan produk dan promosi yang lebih spesifik, seperti menyediakan set dengan desain menarik, instruksi mudah dipahami, dan harga kompetitif untuk kelompok usia yang paling potensial.
# 5. Eksistensi Pelanggan Setia sebagai Aset Bisnis
# Visualisasi pelanggan dengan jumlah transaksi terbanyak memperlihatkan bahwa ada sekelompok orang yang secara rutin membeli produk LEGO. Pola pembelian berulang ini merupakan sinyal kuat adanya pelanggan setia yang berperan besar dalam kontribusi pendapatan. LEGO dapat memanfaatkan informasi ini untuk merancang program loyalitas pelanggan, seperti sistem poin, akses eksklusif ke produk baru, atau diskon khusus. Lebih dari itu, pendekatan berbasis data ini bisa membantu perusahaan mengenal lebih dekat profil pembeli paling aktif dan menyusun strategi personalisasi yang mampu meningkatkan retensi pelanggan serta memperpanjang siklus pembelian mereka.
Note that the echo = FALSE parameter was added to the
code chunk to prevent printing of the R code that generated the
plot.