# Load package
library(dsbox) 
library(ggplot2)
library(dplyr)
## Warning: package 'dplyr' was built under R version 4.4.3
library(tidyr)
library(corrplot)
library(ggthemes)
## Warning: package 'ggthemes' was built under R version 4.4.3
library(patchwork)
## Warning: package 'patchwork' was built under R version 4.4.3
library(cowplot)
## Warning: package 'cowplot' was built under R version 4.4.3

R Markdown

This is an R Markdown document. Markdown is a simple formatting syntax for authoring HTML, PDF, and MS Word documents. For more details on using R Markdown see http://rmarkdown.rstudio.com.

When you click the Knit button a document will be generated that includes both content as well as the output of any embedded R code chunks within the document. You can embed an R code chunk like this:

# Dataset
data("lego_sales")
head(lego_sales)
## # A tibble: 6 × 14
##   first_name last_name   age phone_number set_id number theme     subtheme  year
##   <chr>      <chr>     <dbl> <chr>         <dbl> <chr>  <chr>     <chr>    <dbl>
## 1 Kimberly   Beckstead    24 216-555-2549  24701 76062  DC Comic… Mighty …  2018
## 2 Neel       Garvin       35 819-555-3189  25626 70595  Ninjago   Rise of…  2018
## 3 Neel       Garvin       35 819-555-3189  24665 21031  Architec… <NA>      2018
## 4 Chelsea    Bouchard     41 <NA>          24695 31048  Creator   <NA>      2018
## 5 Chelsea    Bouchard     41 <NA>          25626 70595  Ninjago   Rise of…  2018
## 6 Chelsea    Bouchard     41 <NA>          24721 10831  Duplo     <NA>      2018
## # ℹ 5 more variables: name <chr>, pieces <dbl>, us_price <dbl>,
## #   image_url <chr>, quantity <dbl>
View(lego_sales)
?lego_sales
## starting httpd help server ... done

NO 1

# Muat dataset lego_sales
data("lego_sales")

# Jumlah baris (data) dan kolom
dim(lego_sales)
## [1] 620  14
# Nama kolom dan tipe data
str(lego_sales)
## spc_tbl_ [620 × 14] (S3: spec_tbl_df/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 ...
##  - 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  
## 
# Cek jumlah nilai null per kolom
jumlah_null <- colSums(is.na(lego_sales))
jumlah_null
##   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
# Tangani nilai null jika ada 
df_lego_bersih <- na.omit(lego_sales)
nrow(df_lego_bersih)
## [1] 287
# Cek apakah ada baris yang duplikat
apakah_duplikat <- duplicated(lego_sales)
any(apakah_duplikat)
## [1] FALSE
# Jumlah baris duplikat
jumlah_duplikat <- sum(apakah_duplikat)
jumlah_duplikat
## [1] 0
# Hapus baris duplikat jika ada
if (any(apakah_duplikat)) {
  df_lego_bersih <- lego_sales[!apakah_duplikat, ]
  df_lego <- df_lego_bersih
} else {
  df_lego <- lego_sales
}

dim(df_lego)
## [1] 620  14

NO 2 dan 3

10 customer dengan jumlah terbanyak beserta insight

names(lego_sales)
##  [1] "first_name"   "last_name"    "age"          "phone_number" "set_id"      
##  [6] "number"       "theme"        "subtheme"     "year"         "name"        
## [11] "pieces"       "us_price"     "image_url"    "quantity"
lego_sales %>%
  mutate(Customer = paste(first_name, last_name)) %>%
  group_by(Customer) %>%
  summarise(Total_Sales = sum(us_price * quantity, na.rm = TRUE)) %>%
  arrange(desc(Total_Sales)) %>%
  slice(1:10) %>%
  ggplot(aes(x = reorder(Customer, Total_Sales), y = Total_Sales)) +
  geom_col(fill = "steelblue") +
  coord_flip() +
  labs(
    title = "Top 10 Customer dengan Penjualan Tertinggi",
    x = "Customer",
    y = "Total Sales (USD)"
  ) +
  theme_minimal()

# Insight
cat("Visualisasi Top 10 Customer dengan Penjualan Tertinggi dengan jelas menyoroti bahwa Jennifer Dana merupakan pelanggan dengan kontribusi pendapatan yang paling signifikan, jauh melampaui pelanggan-pelanggan lainnya. Setelah Jennifer Dana, terdapat sekelompok pelanggan seperti Cody Gonzales, Celia Foley, Kaitlyn Degeer, dan Cecilia Mauro yang memiliki tingkat penjualan yang relatif serupa dan menjadi kontributor penting berikutnya. Selanjutnya, terjadi penurunan bertahap dalam total penjualan untuk pelanggan-pelanggan di urutan bawah daftar ini. Dominasi penjualan oleh satu pelanggan utama seperti Jennifer Dana menekankan pentingnya menjaga hubungan baik dan berpotensi mengembangkan penjualan dari pelanggan-pelanggan lain dalam daftar 10 teratas ini untuk diversifikasi pendapatan.")
## Visualisasi Top 10 Customer dengan Penjualan Tertinggi dengan jelas menyoroti bahwa Jennifer Dana merupakan pelanggan dengan kontribusi pendapatan yang paling signifikan, jauh melampaui pelanggan-pelanggan lainnya. Setelah Jennifer Dana, terdapat sekelompok pelanggan seperti Cody Gonzales, Celia Foley, Kaitlyn Degeer, dan Cecilia Mauro yang memiliki tingkat penjualan yang relatif serupa dan menjadi kontributor penting berikutnya. Selanjutnya, terjadi penurunan bertahap dalam total penjualan untuk pelanggan-pelanggan di urutan bawah daftar ini. Dominasi penjualan oleh satu pelanggan utama seperti Jennifer Dana menekankan pentingnya menjaga hubungan baik dan berpotensi mengembangkan penjualan dari pelanggan-pelanggan lain dalam daftar 10 teratas ini untuk diversifikasi pendapatan.

10 Tema LEGO Terpopuler Berdasarkan Penjualan beserta insight

lego_sales %>%
  group_by(theme) %>%
  summarise(total_sales = sum(us_price * quantity, na.rm = TRUE)) %>%
  arrange(desc(total_sales)) %>%
  slice(1:10) %>%
  ggplot(aes(x = reorder(theme, total_sales), y = total_sales)) +
  geom_col(fill = "orchid") +
  coord_flip() +
  labs(title = "10 Tema LEGO Terpopuler Berdasarkan Penjualan",
       x = "Theme", y = "Total Sales (USD)")

# Insight
cat("Berdasarkan visualisasi data penjualan 10 tema LEGO terpopuler, terlihat jelas bahwa tema Star Wars mendominasi pasar dengan angka penjualan yang jauh melampaui tema-tema lainnya. Di sisi lain, Ninjago dan City menunjukkan performa penjualan yang solid dan menempati posisi berikutnya sebagai kontributor utama pendapatan. Menariknya, terdapat disparitas yang cukup signifikan antara tema-tema teratas dan tema-tema di urutan bawah seperti Elves dan Ghostbusters, yang mengindikasikan adanya preferensi konsumen yang kuat terhadap tema-tema tertentu dan potensi adanya pasar niche untuk tema-tema dengan penjualan lebih rendah. Tema Nexo Knights, meskipun berada di posisi tengah atas, mungkin menunjukkan kinerja yang tidak sekuat ekspektasi jika dibandingkan dengan popularitas tema orisinal LEGO lainnya.")
## Berdasarkan visualisasi data penjualan 10 tema LEGO terpopuler, terlihat jelas bahwa tema Star Wars mendominasi pasar dengan angka penjualan yang jauh melampaui tema-tema lainnya. Di sisi lain, Ninjago dan City menunjukkan performa penjualan yang solid dan menempati posisi berikutnya sebagai kontributor utama pendapatan. Menariknya, terdapat disparitas yang cukup signifikan antara tema-tema teratas dan tema-tema di urutan bawah seperti Elves dan Ghostbusters, yang mengindikasikan adanya preferensi konsumen yang kuat terhadap tema-tema tertentu dan potensi adanya pasar niche untuk tema-tema dengan penjualan lebih rendah. Tema Nexo Knights, meskipun berada di posisi tengah atas, mungkin menunjukkan kinerja yang tidak sekuat ekspektasi jika dibandingkan dengan popularitas tema orisinal LEGO lainnya.

Sebaran Jumlah Pieces dan Harga beserta insight

lego_sales %>%
  filter(!is.na(pieces), !is.na(us_price)) %>%
  ggplot(aes(x = pieces, y = us_price)) +
  geom_point(alpha = 0.5, color = "firebrick") +
  geom_smooth(method = "lm", color = "slategray", se = TRUE) +
  labs(title = "Sebaran Jumlah Pieces vs Harga",
       x = "Jumlah Pieces", y = "Harga (USD)") +
  theme_minimal()
## `geom_smooth()` using formula = 'y ~ x'

# Insight
cat("Visualisasi Sebaran Jumlah Pieces vs Harga menunjukkan adanya korelasi positif yang kuat antara jumlah pieces dalam sebuah set LEGO dengan harganya; secara umum, semakin banyak pieces yang terkandung dalam sebuah set, semakin tinggi pula harganya, yang ditunjukkan oleh tren garis regresi yang meningkat. Meskipun demikian, terdapat beberapa outlier di mana set dengan jumlah pieces yang relatif sedikit memiliki harga yang lebih tinggi dari perkiraan tren, atau sebaliknya, menunjukkan bahwa faktor lain selain jumlah pieces juga dapat memengaruhi penetapan harga suatu set LEGO. Sebagian besar set cenderung memiliki jumlah pieces di bawah 1000 dan harga di bawah 100 USD, dengan semakin sedikitnya set yang memiliki jumlah pieces dan harga yang lebih tinggi.")
## Visualisasi Sebaran Jumlah Pieces vs Harga menunjukkan adanya korelasi positif yang kuat antara jumlah pieces dalam sebuah set LEGO dengan harganya; secara umum, semakin banyak pieces yang terkandung dalam sebuah set, semakin tinggi pula harganya, yang ditunjukkan oleh tren garis regresi yang meningkat. Meskipun demikian, terdapat beberapa outlier di mana set dengan jumlah pieces yang relatif sedikit memiliki harga yang lebih tinggi dari perkiraan tren, atau sebaliknya, menunjukkan bahwa faktor lain selain jumlah pieces juga dapat memengaruhi penetapan harga suatu set LEGO. Sebagian besar set cenderung memiliki jumlah pieces di bawah 1000 dan harga di bawah 100 USD, dengan semakin sedikitnya set yang memiliki jumlah pieces dan harga yang lebih tinggi.

Komposisi Penjualan Berdasarkan Usia beserta insight

lego_sales %>%
  group_by(age) %>%
  summarise(total_sales = sum(us_price * quantity, na.rm = TRUE)) %>%
  ggplot(aes(x = factor(age), y = total_sales, fill = factor(age))) +
  geom_col(show.legend = FALSE) +
  labs(title = "Komposisi Penjualan Berdasarkan Usia",
       x = "Usia", y = "Total Sales (USD)") +
  theme_minimal()

# Insight
cat("Grafik Komposisi Penjualan Berdasarkan Usia menampilkan distribusi penjualan LEGO di berbagai kelompok usia, menunjukkan adanya puncak penjualan yang signifikan pada rentang usia 25-27 tahun dan 32-33 tahun, serta peningkatan penjualan yang cukup besar pada usia 20-24 tahun dan 34-42 tahun. Terlihat juga adanya peningkatan penjualan kembali di rentang usia 50-52 tahun, meskipun tidak setinggi kelompok usia sebelumnya. Secara umum, penjualan cenderung lebih rendah pada kelompok usia remaja (16-19 tahun) dan kelompok usia lanjut (di atas 55 tahun), dengan beberapa fluktuasi di antara kelompok usia tersebut, mengindikasikan adanya preferensi pembelian LEGO yang berbeda-beda di setiap tahapan usia dewasa.")
## Grafik Komposisi Penjualan Berdasarkan Usia menampilkan distribusi penjualan LEGO di berbagai kelompok usia, menunjukkan adanya puncak penjualan yang signifikan pada rentang usia 25-27 tahun dan 32-33 tahun, serta peningkatan penjualan yang cukup besar pada usia 20-24 tahun dan 34-42 tahun. Terlihat juga adanya peningkatan penjualan kembali di rentang usia 50-52 tahun, meskipun tidak setinggi kelompok usia sebelumnya. Secara umum, penjualan cenderung lebih rendah pada kelompok usia remaja (16-19 tahun) dan kelompok usia lanjut (di atas 55 tahun), dengan beberapa fluktuasi di antara kelompok usia tersebut, mengindikasikan adanya preferensi pembelian LEGO yang berbeda-beda di setiap tahapan usia dewasa.

Heatmap Korelasi Antar Variabel Numerik beserta insight

data_numerik <- lego_sales[, c("age", "set_id", "year", "pieces", "us_price", "quantity")]
matriks_korelasi <- cor(data_numerik, use = "complete.obs")
## Warning in cor(data_numerik, use = "complete.obs"): the standard deviation is
## zero
library(reshape2)
## Warning: package 'reshape2' was built under R version 4.4.3
## 
## Attaching package: 'reshape2'
## The following object is masked from 'package:tidyr':
## 
##     smiths
korelasi_melted <- melt(matriks_korelasi)
ggplot(korelasi_melted, aes(x = Var1, y = Var2, fill = value)) +
  geom_tile(color = "white") +
  geom_text(aes(label = round(value, 2)), color = "black") +
  scale_fill_gradient2(
    low = "blue", mid = "white", high = "red",
    midpoint = 0, limit = c(-1, 1), name = "Korelasi"
  ) +
  theme_minimal() +
  coord_fixed() +
  theme(
    axis.text.x = element_text(angle = 45, vjust = 1, hjust = 1),
    axis.title.x = element_blank(),
    axis.title.y = element_blank()
  ) +
  labs(title = "Heatmap Korelasi Antar Variabel Numerik")
## Warning: Removed 10 rows containing missing values or values outside the scale range
## (`geom_text()`).

# Insight
cat("Heatmap korelasi antar variabel numerik ini memperlihatkan beberapa hubungan yang menarik, di antaranya korelasi positif yang sangat kuat antara variabel 'pieces' dan 'us_price' (0.94), serta korelasi sempurna antara 'pieces' dan dirinya sendiri (1) dan 'us_price' dengan dirinya sendiri (1). Selain itu, terdapat korelasi positif yang kuat antara 'set_id' dan 'year' (1), yang mengindikasikan kemungkinan adanya pola pemberian ID set berdasarkan tahun rilis. Korelasi negatif tidak terlihat signifikan di antara variabel-variabel ini. Sebagian besar korelasi lainnya cenderung lemah, mendekati nol, seperti korelasi antara 'quantity' dengan variabel lainnya. Variabel 'age' menunjukkan korelasi positif terkuat dengan 'set_id' (1), yang mungkin mengindikasikan bahwa ID set cenderung meningkat seiring bertambahnya usia set (atau sebaliknya, tergantung pada bagaimana 'age' didefinisikan).")
## Heatmap korelasi antar variabel numerik ini memperlihatkan beberapa hubungan yang menarik, di antaranya korelasi positif yang sangat kuat antara variabel 'pieces' dan 'us_price' (0.94), serta korelasi sempurna antara 'pieces' dan dirinya sendiri (1) dan 'us_price' dengan dirinya sendiri (1). Selain itu, terdapat korelasi positif yang kuat antara 'set_id' dan 'year' (1), yang mengindikasikan kemungkinan adanya pola pemberian ID set berdasarkan tahun rilis. Korelasi negatif tidak terlihat signifikan di antara variabel-variabel ini. Sebagian besar korelasi lainnya cenderung lemah, mendekati nol, seperti korelasi antara 'quantity' dengan variabel lainnya. Variabel 'age' menunjukkan korelasi positif terkuat dengan 'set_id' (1), yang mungkin mengindikasikan bahwa ID set cenderung meningkat seiring bertambahnya usia set (atau sebaliknya, tergantung pada bagaimana 'age' didefinisikan).