##
## 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
## corrplot 0.95 loaded
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ forcats 1.0.0 ✔ readr 2.1.5
## ✔ lubridate 1.9.4 ✔ stringr 1.5.1
## ✔ purrr 1.0.4 ✔ tibble 3.2.1
## ── 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
data("lego_sales")
lego_sales <- lego_sales %>% distinct()
# Load dataset
data("lego_sales")
lego_sales <- lego_sales %>% distinct()
# Cek struktur dan ringkasan
cat("Jumlah baris:", nrow(lego_sales), "\n")
## Jumlah baris: 620
cat("Jumlah kolom:", ncol(lego_sales), "\n")
## Jumlah kolom: 14
# Lihat nama kolom dan tipe datanya
str(lego_sales)
## tibble [620 × 14] (S3: tbl_df/tbl/data.frame)
## $ first_name : chr [1:620] "Kimberly" "Neel" "Neel" "Chelsea" ...
## $ last_name : chr [1:620] "Beckstead" "Garvin" "Garvin" "Bouchard" ...
## $ age : num [1:620] 24 35 35 41 41 41 19 19 37 37 ...
## $ phone_number: chr [1:620] "216-555-2549" "819-555-3189" "819-555-3189" NA ...
## $ set_id : num [1:620] 24701 25626 24665 24695 25626 ...
## $ number : chr [1:620] "76062" "70595" "21031" "31048" ...
## $ theme : chr [1:620] "DC Comics Super Heroes" "Ninjago" "Architecture" "Creator" ...
## $ subtheme : chr [1:620] "Mighty Micros" "Rise of the Villains" NA NA ...
## $ year : num [1:620] 2018 2018 2018 2018 2018 ...
## $ name : chr [1:620] "Robin vs. Bane" "Ultra Stealth Raider" "Burj Khalifa" "Lakeside Lodge" ...
## $ pieces : num [1:620] 77 1093 333 368 1093 ...
## $ us_price : num [1:620] 9.99 119.99 39.99 29.99 119.99 ...
## $ image_url : chr [1:620] "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:620] 1 1 1 1 1 1 1 3 1 2 ...
# Tampilkan ringkasan statistik
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 :24804 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
##
# 1. Cek dan hapus duplikat
cat("Jumlah data duplikat:", sum(duplicated(lego_sales)), "\n")
## Jumlah data duplikat: 0
lego_sales <- lego_sales %>% distinct()
# 2. Cek missing value
cat("Jumlah nilai NA:", sum(is.na(lego_sales)), "\n")
## Jumlah nilai NA: 392
# Lihat jumlah NA per kolom
colSums(is.na(lego_sales))
## 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
# Hapus baris dengan NA kalau memang perlu:
lego_sales <- lego_sales %>% drop_na()
# Visualisasi 1: 10 Custemer dengan Transaksi Terbanyak
lego_sales %>%
group_by(first_name, last_name) %>%
summarise(Total_Transaksi = sum(quantity, na.rm = TRUE), .groups = "drop") %>%
arrange(desc(Total_Transaksi)) %>%
slice_max(Total_Transaksi, n = 10) %>%
ggplot(aes(x = reorder(paste(first_name, last_name), Total_Transaksi), y = Total_Transaksi)) +
geom_bar(stat = "identity", fill = "grey") +
coord_flip() +
labs(title = "10 Customer dengan Transaksi Terbanyak",
x = "Nama Customer",
y = "Total Transaksi") +
theme_minimal()
Note that the
echo = FALSE parameter was added to the code
chunk to prevent printing of the R code that generated the plot.
# Visualisasi 2: 10 Tema LEGO Terpopuler Berdasarkan Penjualan
lego_sales %>%
group_by(theme) %>%
summarise(Total_Quantity = sum(quantity, na.rm = TRUE)) %>%
arrange(desc(Total_Quantity)) %>%
slice_max(Total_Quantity, n = 10) %>%
ggplot(aes(x = reorder(theme, Total_Quantity), y = Total_Quantity)) +
geom_bar(stat = "identity", fill = "steelblue") +
coord_flip() +
labs(title = "10 Tema LEGO Terpopuler", x = "Tema", y = "Unit Terjual") +
theme_light()
# Visualisasi 3: Sebaran Jumlah Pieces dan Harga
lego_sales %>%
ggplot(aes(x = pieces, y = us_price)) +
geom_point(alpha = 0.5, color = "darkgreen") +
labs(title = "Sebaran Jumlah Pieces dan Harga", x = "Jumlah Pieces", y = "Harga (USD)") +
theme_minimal()
# Visualisasi 4: Komposisi Penjualan Berdasarkan Usia
lego_sales %>%
group_by(age) %>%
summarise(total_quantity = sum(quantity, na.rm = TRUE)) %>%
ggplot(aes(x = age, y = total_quantity)) +
geom_col(fill = "pink") +
labs(title = "Penjualan LEGO Berdasarkan Usia", x = "Usia", y = "Total Penjualan") +
theme_minimal()
# Visualisasi 5: Heatmap Korelasi
data_num <- lego_sales %>%
select_if(is.numeric) %>%
drop_na()
cor_matrix <- cor(data_num)
## Warning in cor(data_num): the standard deviation is zero
corrplot(cor_matrix, method = "color", type = "upper", addCoef.col = "black", tl.cex = 0.8, number.cex = 0.7)
Tema ‘Star Wars’ mendominasi total penjulan. Narasi: Tema seperti ‘Star Wars’, ‘Ninjago’, dan ‘City’ mendominasi penjualan berdasarkan kuantitas. Ini menunjukkan preferensi konsumen terhadap tema-tema berlisensi dan tema klasik LEGO.
Semakin banyak pieces, cenderung semakin mahal. Narasi: Terdapat pola yang menunjukkan bahwa semakin banyak jumlah pieces, semakin mahal harga set LEGO tersebut. Namun, terdapat beberapa pengecualian yang bisa terjadi karena faktor lisensi atau eksklusivitas tema.
Kelompok usia 30-45 tahun merupakan pembeli terbanyak. Narasi: Penjualan terbanyak berasal dari kelompok usia 30–45 tahun. Ini bisa menunjukkan bahwa pembeli LEGO tidak hanya anak-anak, tetapi juga orang dewasa (mungkin kolektor atau orang tua).
Korelasi positif antara pieces dan harga. Narasi: Heatmap
menunjukkan korelasi positif yang kuat antara pieces dan
us_price, serta hubungan moderat dengan
quantity. Korelasi ini penting untuk memahami faktor yang
mempengaruhi harga dan pembelian.
Beberapa customer membeli lebih dari 3 unit LEGO secara berulang. Narasi: Beberapa customer muncul sebagai pembeli dengan frekuensi tinggi, bahkan hingga membeli lebih dari 3 unit. Hal ini dapat menunjukkan loyalitas atau minat besar terhadap produk LEGO tertentu. —