# clear-up the environment
rm(list = ls())

# chunk options
knitr::opts_chunk$set(
  message = FALSE,
  warning = FALSE,
  fig.align = "center",
  comment = "#>"
)

1 Pendahuluan

Artikel ini dibuat untuk memenuhi tugas Learning by Building (LBB) pada materi DV - Data Visualization. Materi berikut ditujukan untuk semua orang yang tertarik pada bidang Data Science dan R-Language secara umum. Materi ini dipersilahkan untuk direproduksi, didistribusikan, diterjemahkan, atau diadaptasikan sesuai dengan kebutuhan pembaca.

Penulis tertarik mengangkat topik tentang Pizza Sales karena penulis mendapatkan referensi dataset yang dirasa cukup lengkap untuk diolah dan ini cukup menarik karena penulis juga menyukai dan sering menikmati Pizza, dan ingin mengetahui bagaimana trend penjualan Pizza terjadi. Dalam hal ini penulis mencoba role-playing sebagai Data Consultant/Analyst di sebuah Toko Pizza bernama El-Capitan Pizza Resto.

Selain itu, data analysis dan data visualization untuk sebuah pertanyaan bisnis sangat cocok untuk material yang berkaitan dengan penjualan (sales), maka dari itu pemilih memilih untuk mengolah dataset ini untuk dijadikan material tugas di Algoritma : Data Visualization Course.

knitr::include_graphics("images/pizza-enak.jpg")

Artikel ini bertujuan untuk eksplorasi data dan visualisasi data dari penjualan berbagai jenis Pizza di sebuah toko. Susunan dari artikel ini terdiri dari metodologi untuk proses analisa data diantaranya : Seleksi Dataset, Data Cleaning dan Pre-Processing, Eksplorasi Data, dan Visualisasi Data.

Setiap langkah dari metodologi ini akan diikuti oleh penjelasan yang dijabarkan oleh Penulis untuk memperjelas maksud dan tujuan dari setiap langkah yang dilakukan. Selain itu juga dapat bermanfaat untuk pembaca ketika ingin mencoba memulai belajar untuk mengolah sebuah dataset.

2 Import Data dan Pre-Processing

Pada bagian ini, Penulis akan coba menjabarkan proses pengambilan data dan proses awal apa saja yang harus dilakukan agar sebuah dataset siap untuk dianalisa.

2.1 Import Library

Penulis akan menggunakan beberapa library pada Artikel ini. Berhubung dataset dan artikel ini kemungkinan akan dikembangkan untuk Tugas LBB yang lainnya, penulis akan mengupload library yang akan digunakan pada materi selanjutnya sehingga dokumen lebih futureproof.

# load library
options(scipen = 99) #me-non-aktifkan scientific annotation
library(tidyverse) #koleksi beberapa library R
library(dplyr) #grammar of data manipulation
library(readr) #membaca data
library(ggplot2) #plot statis
library(plotly) #plot interaktif
library(glue) #setting tooltip
library(lubridate) #treatment date column
library(scales) # mengatur skala pada plot
library(readxl) #import data excel

2.2 Import dan Cek Data

Data ditaruh pada folder data_input pada working directory dimana file R Markdown penulis tempatkan.

#import Dataset
pizza_sales <- read_excel("data_input/datamodel-pizzasales.xlsx", sheet = "pizza_sales")

#glimpse Dataset
glimpse(pizza_sales)
#> Rows: 48,620
#> Columns: 12
#> $ order_details_id  <dbl> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 1…
#> $ order_id          <dbl> 1, 2, 2, 2, 2, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 9, 9…
#> $ pizza_id          <chr> "hawaiian_m", "classic_dlx_m", "five_cheese_l", "ita…
#> $ quantity          <dbl> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1…
#> $ order_date        <dttm> 2015-01-01, 2015-01-01, 2015-01-01, 2015-01-01, 201…
#> $ order_time        <dttm> 1899-12-31 11:38:36, 1899-12-31 11:57:40, 1899-12-3…
#> $ unit_price        <dbl> 13.25, 16.00, 18.50, 20.75, 16.00, 20.75, 16.50, 20.…
#> $ total_price       <dbl> 13.25, 16.00, 18.50, 20.75, 16.00, 20.75, 16.50, 20.…
#> $ pizza_size        <chr> "M", "M", "L", "L", "M", "L", "M", "L", "M", "M", "S…
#> $ pizza_category    <chr> "Classic", "Classic", "Veggie", "Supreme", "Veggie",…
#> $ pizza_ingredients <chr> "Sliced Ham, Pineapple, Mozzarella Cheese", "Peppero…
#> $ pizza_name        <chr> "The Hawaiian Pizza", "The Classic Deluxe Pizza", "T…

Deskripsi Kolom :

  • ‘order_details_id’ : Order Details ID untuk Tiap Transaksi per Jenis Pizza
  • ‘order_id’ : Order ID per Transaksi
  • ‘pizza_id’ : ID Jenis/Tipe Pizza
  • ‘quantity’ : Jumlah Pizza yang dipesan
  • ‘order_date’ : Tanggal Pemesanan
  • ‘order_time’ : Jam Pemesanan
  • ‘unit_price’ : Harga Tiap Pizza
  • ‘total_price’ : Total Harga -> Harga Tiap Pizza x Jumlah Pizza yang dipesan
  • ‘pizza_size’ : Ukuran Pizza
  • ‘pizza_category’ : Kategori Pizza
  • ‘pizza_ingredients’ : Bahan Baku Pizza untuk Topping
  • ‘pizza_name’ : Nama Produk Pizza

Berdasarkan glimpse di atas, ada beberapa kolom yang perlu diganti jenisnya untuk memudahkan processing data.

2.3 Cleansing Data

Pada bagian ini, Penulis akan melakukan beberapa pengecekan yang umum dilakukan pada sebuah dataset sebelum memulai proses data analisis seperti cek ukuran data awal, cek missing value, cek tipe data pada kolom. Lalu setelah itu, Penulis melakukan treatment untuk berbagai kondisi yang ditemui pada dataset yang dicek.

#cek ukuran data sebelum cleansing
nrow(pizza_sales)
#> [1] 48620
#cek missing value
colSums(is.na(pizza_sales))
#>  order_details_id          order_id          pizza_id          quantity 
#>                 0                 0                 0                 0 
#>        order_date        order_time        unit_price       total_price 
#>                 0                 0                 0                 0 
#>        pizza_size    pizza_category pizza_ingredients        pizza_name 
#>                 0                 0                 0                 0
#cek jenis class untuk kolom pizza_ingredients
class(pizza_sales$pizza_ingredients[5])
#> [1] "character"

Penulis merasa bahwa value di Column “pizza_ingredients” memiliki potensi untuk dianalisa, sehingga akan lebih mudah apabila Penulis mengkonversikan value tersebut menjadi data list agar memudahkan data processing

#converting value di column 'pizza_ingredients' menjadi list

pizza_sales$pizza_ingredients <- lapply(strsplit(as.character(pizza_sales$pizza_ingredients),
                                                 "[][']|,\\s*"), function(x) x[nzchar(x)])
class(pizza_sales$pizza_ingredients[5])
#> [1] "list"
pizza_sales$pizza_ingredients[5]
#> [[1]]
#> [1] "Tomatoes"         "Red Peppers"      "Jalapeno Peppers" "Red Onions"      
#> [5] "Cilantro"         "Corn"             "Chipotle Sauce"   "Garlic"
#mengganti jenis kolom
pizza_sales_clean <-
  pizza_sales %>%
  mutate(
    unit_price = as_factor(unit_price),
    pizza_size = as_factor(pizza_size),
    pizza_category = as_factor(pizza_category),
    pizza_name = as_factor(pizza_name)
  )
glimpse(pizza_sales_clean)
#> Rows: 48,620
#> Columns: 12
#> $ order_details_id  <dbl> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 1…
#> $ order_id          <dbl> 1, 2, 2, 2, 2, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 9, 9…
#> $ pizza_id          <chr> "hawaiian_m", "classic_dlx_m", "five_cheese_l", "ita…
#> $ quantity          <dbl> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1…
#> $ order_date        <dttm> 2015-01-01, 2015-01-01, 2015-01-01, 2015-01-01, 201…
#> $ order_time        <dttm> 1899-12-31 11:38:36, 1899-12-31 11:57:40, 1899-12-3…
#> $ unit_price        <fct> 13.25, 16, 18.5, 20.75, 16, 20.75, 16.5, 20.75, 16.5…
#> $ total_price       <dbl> 13.25, 16.00, 18.50, 20.75, 16.00, 20.75, 16.50, 20.…
#> $ pizza_size        <fct> M, M, L, L, M, L, M, L, M, M, S, S, S, S, S, S, L, L…
#> $ pizza_category    <fct> Classic, Classic, Veggie, Supreme, Veggie, Chicken, …
#> $ pizza_ingredients <list> <"Sliced Ham", "Pineapple", "Mozzarella Cheese">, <…
#> $ pizza_name        <fct> "The Hawaiian Pizza", "The Classic Deluxe Pizza", "T…
#cek ukuran data
nrow(pizza_sales_clean)
#> [1] 48620

Data sudah dianggap ‘clean’ dan bisa digunakan untuk proses selanjutnya yaitu data analisis.

3 Eksplorasi Data dan Visualisasi Data

Untuk memudahkan proses Eksplorasi dan Visualisasi Data, Penulis membuat beberapa pertanyaan bisnis dengan role-playing lagi menjadi seorang Pemilik Bisnis. Pada kasus ini, dataset adalah berupa penjualan ‘Pizza’ setiap harinya di Tahun 2015. Sebagai pemilik bisnis, penulis ingin mengetahui beberapa pertanyaan untuk menyusun strategi bisnis di tahun depan.

Pertanyaan Bisnis di EL-Capitan Pizza Resto

  • 1. Bagaimana kesimpulan penjualan Pizza berdasarkan Menu ?
  • 1.A - Summary Penjualan Pizza berdasarkan Nama Pizza
  • 1.B - Summary Penjualan Pizza berdasarkan Size Pizza
  • 1.C - Summary Penjualan Pizza berdasarkan Kategori Pizza

Pemilik Bisnis bisa menentukan strategi marketing yang tepat untuk tahun depan.

  • 2. Bagaimana penjualan Pizza terhadap waktu?
  • 1.A - Penjualan Pizza terhadap Bulan
  • 1.B - Penjualan Pizza terhadap Hari
  • 1.C - Penjualan Pizza terhadap Jam

Pemilik Bisnis bisa menentukan strategi jam kerja, hari libur, periode cuti yang efektif dan efisien untuk para karyawan dan secara bisnis.

  • 3. Menu Pizza apakah yang paling menguntungkan?

Pemilik Bisnis bisa menentukan besaran profit margin untuk Menu tertentu.

  • 4. Bagaimana Pemakaian Bahan Baku di El-Capitan Pizza Resto?

Pemilik Bisnis bisa memprediksi untuk trend pembelian stok bahan baku Pizza dalam satu tahun

knitr::include_graphics("images/pizza-kitchen.jpg")

3.1 Penjualan Pizza berdasarkan Jenis Menu

Penulis membagi penjualan menjadi beberapa plot sebagai berikut.

3.1.1 Penjualan Pizza berdasarkan Nama

#agregasi data
pizza_sales_name <-
  pizza_sales_clean %>%
  group_by(pizza_name) %>%
  summarise(total_pizza_sales = sum(quantity)) %>%
  ungroup() %>%
  arrange(desc(total_pizza_sales)) %>%
  mutate(label = glue("Total : {comma(total_pizza_sales)}
                      Name : {pizza_name}"))
pizza_sales_name

3.1.2 Penjualan Pizza berdasarkan Size

#agregasi data
pizza_sales_size <-
  pizza_sales_clean %>%
  group_by(pizza_size) %>%
  summarise(total_pizza_sales = sum(quantity)) %>%
  ungroup() %>%
  mutate(label = glue("Total : {comma(total_pizza_sales)}
                      Name : {pizza_size}")) %>%
  mutate(percentage = total_pizza_sales/sum(total_pizza_sales))
pizza_sales_size

3.1.3 Penjualan Pizza berdasarkan Kategori

#agregasi data
pizza_sales_cat <-
  pizza_sales_clean %>%
  group_by(pizza_category) %>%
  summarise(total_pizza_sales = sum(quantity)) %>%
  ungroup() %>%
  arrange(desc(total_pizza_sales)) %>%
  mutate(label = glue("Total : {comma(total_pizza_sales)}
                      Name : {pizza_category}")) 
pizza_sales_cat

3.1.4 Insight

Penulis menarik beberapa insight sebagai saran untuk strategi bisnis dari sisi Menu Pizza yang ditawarkan di Restoran Pizza

  • Untuk menu The Brie Carrie Pizza sebaiknya dipromosikan agar penjualan bertambah karena merupakan Menu yang paling kurang diminati oleh Pelanggan
  • Untuk size XXL bisa dihapus apabila tidak begitu menguntungkan dari sisi bisnis karena penjualan sangat sedikit, atau dipromosikan apabila ingin memperkuat lini produk bisnis.

3.2 Penjualan Pizza berdasarkan Waktu

Penulis membagi penjualan menjadi berdasarkan Bulan, Hari, dan Jam.

3.2.1 Penjualan berdasarkan Bulan

#membuat kolom baru untuk jenis bulan
pizza_sales_clean$month_sales <- month(pizza_sales_clean$order_date, 
                                       label = TRUE)

#agregasi jumlah penjualan pizza tiap bulan
pizza_month_sales <- 
  pizza_sales_clean %>%
  group_by(month_sales) %>%
  summarise(total_pizza = sum(quantity)) %>% 
  ungroup() %>%
  arrange(month_sales) %>%
  mutate(label = glue("Month : {month_sales}
                      Total Pizza : {comma(total_pizza)}"))
pizza_month_sales

3.2.2 Penjualan berdasarkan Hari

#membuat kolom baru untuk jenis hari
pizza_sales_clean$day_sales <- wday(pizza_sales_clean$order_date, label = TRUE)

#agregasi jumlah penjualan pizza tiap hari
pizza_day_sales <- 
  pizza_sales_clean %>%
  group_by(day_sales) %>%
  summarise(total_pizza = sum(quantity)) %>% 
  ungroup() %>%
  arrange(day_sales) %>%
  mutate(label = glue("Day : {day_sales}
                      Total Pizza : {comma(total_pizza)}"))
pizza_day_sales

3.2.3 Penjualan berdasarkan Jam

#membuat kolom baru untuk jam penjualan
pizza_sales_clean$hour_sales <- hour(pizza_sales_clean$order_time)

#agregasi jumlah penjualan pizza per jam
pizza_hour_sales <- 
  pizza_sales_clean %>%
  group_by(hour_sales) %>%
  summarise(total_pizza = sum(quantity)) %>% 
  ungroup() %>%
  arrange(hour_sales) %>%
  mutate(label = glue("Hour : {hour_sales}
                      Total Pizza : {comma(total_pizza)}"))
pizza_hour_sales

3.2.4 Insight

Penulis menarik beberapa insight sebagai saran untuk strategi pengaturan tenaga kerja di Restoran

  • Untuk bulan Februari, September, Oktober merupakan bulan dengan penjualan paling rendah sehingga untuk perizinan cuti karyawan bisa lebih dilonggarkan pada bulan-bulan tersebut.
  • Untuk jadwal hari libur dapat dilakukan di Hari Minggu dan Senin karena penjualan pada kedua hari tersebut relatif rendah dibandingkan dengan penjualan di hari lainnya
  • Dengan asumsi awal jam masuk kerja di Jam 8 dan persiapan Toko adalah 1 jam, akan lebih efektif apabila jam masuk kerja di geser ke Jam 9 dan Toko dibuka Jam10 karena penjualan di Jam 9 sangat amat sedikit.
  • Untuk Jam Istirahat pekerja dapat dilakukan paling banyak secara bergantian untuk tiap karyawan pada Jam 14 hingga Jam 15 karena pada jam tersebut penjualan relatif menurun dibandingkan dua Peak-Hour yaitu Jam Makan Siang : Jam 12 dan Jam Makan Malam : Jam 17 - Jam 18

3.4 Bahan Baku yang digunakan di Tahun 2015

Penulis memanfaatkan kolom ‘pizza_ingredients’ yang telah penulis konversi menjadi List untuk selanjutnya digunakan untuk Analisis.

tail(pizza_sales_clean)
#pembuatan dataframe
ingredient_data <-
  pizza_sales_clean %>%
  select(order_date, order_time, order_id, quantity, pizza_ingredients, pizza_name) 
#agregasi data untuk menghitung total jumlah bahan baku
ingredient_total <-
  ingredient_data %>%
  tidyr::unnest_longer(pizza_ingredients) %>%
  group_by(pizza_ingredients) %>%
  summarise(n = sum(quantity)) %>%
  arrange(desc(n)) %>%
  mutate(label = glue("Total Item : {comma(n)}
                      Pizza Name : {pizza_ingredients}"))

ingredient_total

Data ini bisa dikalikan dengan proporsi bahan baku per pizza, karena di Dataframe tidak tersedia, Penulis asumsikan value nya = 1 di setiap Pizza.

3.4.1 Summary

  • Dari dua Plot diatas, dapat dilihat bahwa rempah-rempah seperti bawang, tomat, bawang merah, dan merica menempati tempat teratas pada jumlah bahan baku yang dipakai. Ini bisa dimanfaatkan oleh pemilik bisnis untuk menentukan pembelian dengan volume besar untuk mendapat diskon dari Supplier.

  • Perlu diperhatikan untuk bahan baku dengan pembelian dibawah 2500 per Tahun untuk memesan secara hati-hati dan melihat trend penjualan per hari agar tidak overstock dan bahan baku akhirnya tidak terpakai karena rusak.