Project Data Analytics: Coffee Shop

Author

Aep Hidayatuloh

Published

May 30, 2023

Latar Belakang

Project data analisis kali ini menggunakan data coffee shop yang sudah dimodifikasi dan disesuaikan. Data tersebut dapat Anda akses melalui repository GitHub.

Project coffee shop ini cukup menarik untuk dijadikan sebagai salah satu portofolio data analytics. Data ini menceritakan tentang penjualan di sebuah coffeeshop selama satu bulan, yaitu April 2019. Selain data transaksi, ada juga data pelanggan, pegawai, produk dan target. Dengan data ini kita dapat melakukan beberapa teknik di dalam data analytics, mulai dari penyiapan data hingga pembuatan laporan atau report.

Objective

Mengelompokkan pelanggan agar dapat menentukan strategi pemasaran kepada masing-masing kelompok.

Packages

library(tidyverse)
── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
✔ dplyr     1.1.2     ✔ readr     2.1.4
✔ forcats   1.0.0     ✔ stringr   1.5.0
✔ ggplot2   3.4.2     ✔ tibble    3.2.1
✔ lubridate 1.9.2     ✔ tidyr     1.3.0
✔ purrr     1.0.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
library(scales)
library(readxl)

Eksplorasi Data Penjualan

Data utama yang digunakan dalam project ini adalah transaksi penjualan selama bulan April 2019.

penjualan <- read_xlsx("../Data/coffeeshop/penjualan201904.xlsx")
penjualan
# A tibble: 49,894 × 12
   id_transaksi tgl_transaksi       wkt_transaksi       id_outlet_penjualan
          <dbl> <dttm>              <dttm>                            <dbl>
 1            7 2019-04-01 00:00:00 1899-12-31 12:04:43                   3
 2           11 2019-04-01 00:00:00 1899-12-31 15:54:39                   3
 3           19 2019-04-01 00:00:00 1899-12-31 14:34:59                   3
 4           32 2019-04-01 00:00:00 1899-12-31 16:06:04                   3
 5           33 2019-04-01 00:00:00 1899-12-31 19:18:37                   3
 6           39 2019-04-01 00:00:00 1899-12-31 18:54:46                   3
 7           50 2019-04-01 00:00:00 1899-12-31 13:03:49                   3
 8           53 2019-04-01 00:00:00 1899-12-31 11:21:14                   3
 9           59 2019-04-01 00:00:00 1899-12-31 19:30:55                   3
10           62 2019-04-01 00:00:00 1899-12-31 12:01:00                   3
# ℹ 49,884 more rows
# ℹ 8 more variables: id_pegawai <dbl>, id_pelanggan <dbl>,
#   makan_ditempat <chr>, id_produk <dbl>, kuantitas <dbl>, harga_satuan <dbl>,
#   total_harga <dbl>, produk_promo <chr>
penjualan |> 
  glimpse()
Rows: 49,894
Columns: 12
$ id_transaksi        <dbl> 7, 11, 19, 32, 33, 39, 50, 53, 59, 62, 81, 90, 91,…
$ tgl_transaksi       <dttm> 2019-04-01, 2019-04-01, 2019-04-01, 2019-04-01, 2…
$ wkt_transaksi       <dttm> 1899-12-31 12:04:43, 1899-12-31 15:54:39, 1899-12…
$ id_outlet_penjualan <dbl> 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,…
$ id_pegawai          <dbl> 12, 17, 17, 12, 17, 17, 12, 12, 12, 12, 12, 17, 12…
$ id_pelanggan        <dbl> 558, 781, 788, 683, 99, 664, 316, 38, 370, 180, 35…
$ makan_ditempat      <chr> "N", "N", "Y", "N", "Y", "Y", "N", "N", "Y", "Y", …
$ id_produk           <dbl> 52, 27, 46, 23, 34, 32, 49, 60, 51, 49, 35, 47, 25…
$ kuantitas           <dbl> 1, 2, 2, 2, 1, 1, 2, 1, 2, 2, 2, 1, 2, 2, 2, 2, 1,…
$ harga_satuan        <dbl> 2.50, 3.50, 2.50, 2.50, 2.45, 3.00, 3.00, 3.75, 3.…
$ total_harga         <dbl> 2.50, 7.00, 5.00, 5.00, 2.45, 3.00, 6.00, 3.75, 6.…
$ produk_promo        <chr> "N", "N", "N", "N", "N", "N", "N", "N", "N", "N", …
data.frame(Variabel = colnames(penjualan)) |> 
  bind_cols(
    tribble(
      ~Keterangan, 
      "No identitas transaksi", 
      "Tanggal transaksi", 
      "Waktu transaksi", 
      "No identitas outlet penjualan", 
      "No identitas pegawai", 
      "No identitas pelanggan", 
      "Pesanan dimakan di tempat? Y=Yes, N=No", 
      "No identias produk", 
      "Banyaknya produk yang dibeli", 
      "Harga satuan produk", 
      "Total harga yang harus dibayar", 
      "Produk dalam periode promo? Y=Yes, N=No"
    )
  )
              Variabel                              Keterangan
1         id_transaksi                  No identitas transaksi
2        tgl_transaksi                       Tanggal transaksi
3        wkt_transaksi                         Waktu transaksi
4  id_outlet_penjualan           No identitas outlet penjualan
5           id_pegawai                    No identitas pegawai
6         id_pelanggan                  No identitas pelanggan
7       makan_ditempat  Pesanan dimakan di tempat? Y=Yes, N=No
8            id_produk                      No identias produk
9            kuantitas            Banyaknya produk yang dibeli
10        harga_satuan                     Harga satuan produk
11         total_harga          Total harga yang harus dibayar
12        produk_promo Produk dalam periode promo? Y=Yes, N=No
skimr::skim(penjualan)
Data summary
Name penjualan
Number of rows 49894
Number of columns 12
_______________________
Column type frequency:
character 2
numeric 8
POSIXct 2
________________________
Group variables None

Variable type: character

skim_variable n_missing complete_rate min max empty n_unique whitespace
makan_ditempat 294 0.99 1 1 0 2 0
produk_promo 0 1.00 1 1 0 2 0

Variable type: numeric

skim_variable n_missing complete_rate mean sd p0 p25 p50 p75 p100 hist
id_transaksi 0 1 869.06 857.86 1.0 223.0 481.00 1401.00 4203 ▇▂▂▁▁
id_outlet_penjualan 0 1 5.35 2.07 3.0 3.0 5.00 8.00 8 ▇▇▁▁▇
id_pegawai 0 1 25.36 12.47 6.0 15.0 26.00 41.00 45 ▅▇▅▁▇
id_pelanggan 0 1 2282.32 3240.55 0.0 0.0 0.00 5412.00 8501 ▇▁▁▂▂
id_produk 0 1 47.88 17.93 1.0 33.0 47.00 60.00 87 ▁▆▇▆▅
kuantitas 0 1 1.44 0.54 1.0 1.0 1.00 2.00 8 ▇▁▁▁▁
harga_satuan 0 1 3.38 2.68 0.8 2.5 3.00 3.75 45 ▇▁▁▁▁
total_harga 0 1 4.68 4.44 0.0 3.0 3.75 6.00 360 ▇▁▁▁▁

Variable type: POSIXct

skim_variable n_missing complete_rate min max median n_unique
tgl_transaksi 0 1 2019-04-01 00:00:00 2019-04-29 00:00:00 2019-04-15 00:00:00 29
wkt_transaksi 0 1 1899-12-31 01:00:44 1899-12-31 20:59:32 1899-12-31 11:18:25 26074

Beberapa temuan sementara diantaranya:
- Ada 49,894 baris dan 12 variabel, terdiri dari 2 variabel character, 8 variabel numeric dan 2 variabel POSIXct atau datetime.
- Ada sebanyak 294 baris data yang memiliki data hilang (missing value) pada variabel makan_ditempat. Dengan kata lain, missing value sebanyak ~0.58925% dari seluruh baris data.
- Perlu mengubah jenis data pada variabel tgl_transaksi menjadi date sehingga hanya format date saja.
- Perlu mengubah dan menyesuaikan tanggal pada variabel wkt_transaksi agar tanggalnya sama dengan tgl_transaksi.

Data Preparation

Mengubah dan menggabungkan variable waktu transaksi dengan tanggal transaksi sehingga tanggal pada variabel waktu transaksi sama dengan yang ada pada variabel tanggal transaksi.

penjualan <- penjualan |> 
  mutate(
    wkt_transaksi = tgl_transaksi %m+% seconds(wkt_transaksi %m+% days(1) %m+% years(70))
  )
penjualan
# A tibble: 49,894 × 12
   id_transaksi tgl_transaksi       wkt_transaksi       id_outlet_penjualan
          <dbl> <dttm>              <dttm>                            <dbl>
 1            7 2019-04-01 00:00:00 2019-04-01 12:04:43                   3
 2           11 2019-04-01 00:00:00 2019-04-01 15:54:39                   3
 3           19 2019-04-01 00:00:00 2019-04-01 14:34:59                   3
 4           32 2019-04-01 00:00:00 2019-04-01 16:06:04                   3
 5           33 2019-04-01 00:00:00 2019-04-01 19:18:37                   3
 6           39 2019-04-01 00:00:00 2019-04-01 18:54:46                   3
 7           50 2019-04-01 00:00:00 2019-04-01 13:03:49                   3
 8           53 2019-04-01 00:00:00 2019-04-01 11:21:14                   3
 9           59 2019-04-01 00:00:00 2019-04-01 19:30:55                   3
10           62 2019-04-01 00:00:00 2019-04-01 12:01:00                   3
# ℹ 49,884 more rows
# ℹ 8 more variables: id_pegawai <dbl>, id_pelanggan <dbl>,
#   makan_ditempat <chr>, id_produk <dbl>, kuantitas <dbl>, harga_satuan <dbl>,
#   total_harga <dbl>, produk_promo <chr>
penjualan |> 
  count(id_pelanggan, id_transaksi, id_outlet_penjualan, id_produk, sort = TRUE) |> 
  filter(id_pelanggan != 0)
# A tibble: 24,343 × 5
   id_pelanggan id_transaksi id_outlet_penjualan id_produk     n
          <dbl>        <dbl>               <dbl>     <dbl> <int>
 1          368          184                   3        55     3
 2          370          148                   3        38     3
 3          440           11                   3        38     3
 4          565           10                   3        41     3
 5          591          376                   3        40     3
 6         5083          207                   5        71     3
 7         5563          206                   5        71     3
 8         5704          207                   5        71     3
 9         8049          210                   8        71     3
10            1          662                   3        28     2
# ℹ 24,333 more rows
penjualan |> 
  filter(id_pelanggan == 0) |>
  group_by(id_pelanggan, id_transaksi, id_outlet_penjualan, id_produk) |> 
  summarise(
    total_kuantitas = sum(kuantitas)
  )
`summarise()` has grouped output by 'id_pelanggan', 'id_transaksi',
'id_outlet_penjualan'. You can override using the `.groups` argument.
# A tibble: 23,165 × 5
# Groups:   id_pelanggan, id_transaksi, id_outlet_penjualan [7,672]
   id_pelanggan id_transaksi id_outlet_penjualan id_produk total_kuantitas
          <dbl>        <dbl>               <dbl>     <dbl>           <dbl>
 1            0            1                   3        42               2
 2            0            1                   3        47               2
 3            0            1                   5        30               1
 4            0            1                   5        31               2
 5            0            1                   5        37               2
 6            0            1                   5        38               1
 7            0            1                   5        44               1
 8            0            1                   5        63               1
 9            0            1                   5        64               2
10            0            1                   5        72               1
# ℹ 23,155 more rows