BELAJAR DATA SCIENCE MENYENANGKAN


SOAL UTS

# Memuat pustaka utama
library(dplyr)

# Membaca dataset ke dalam objek df_penjualan dan menyesuaikan tipe Tanggal
df_penjualan <- read.csv("D:/lab/datasets/raw/data_penjualan.csv")
df_penjualan$Tanggal <- as.Date(df_penjualan$Tanggal)

# Menampilkan 10 baris pertama
head(df_penjualan, 10)
##    ID_Transaksi    Tanggal   Cabang   Admin    Kategori           Produk
## 1       TRX0001 2025-01-01  Jakarta    Maya  Elektronik   Smartwatch Fit
## 2       TRX0002 2025-01-01 Semarang    Budi Alat Kantor  Kertas A4 (Rim)
## 3       TRX0003 2025-01-02  Bandung   Putri    Aksesori Power Bank 20000
## 4       TRX0004 2025-01-05  Bandung   Wawan  Elektronik      Earbuds Pro
## 5       TRX0005 2025-01-05 Semarang    Budi Alat Kantor  Kertas A4 (Rim)
## 6       TRX0006 2025-01-09 Surabaya Lestari  Elektronik   Smartwatch Fit
## 7       TRX0007 2025-01-10  Jakarta    Sari Alat Kantor Paket Alat Tulis
## 8       TRX0008 2025-01-12  Bandung   Putri Alat Kantor  Kertas A4 (Rim)
## 9       TRX0009 2025-01-12  Jakarta    Sari  Elektronik      Earbuds Pro
## 10      TRX0010 2025-01-13 Surabaya Lestari  Elektronik    Smartphone X5
##    Harga_Satuan Jumlah Diskon_Persen Total_Penjualan Metode_Pembayaran
## 1       1800000      2             0         3600000          E-Wallet
## 2         55000      3            15          140250      Kartu Kredit
## 3        280000      6             5         1596000             Tunai
## 4        650000      5            15         2762500          E-Wallet
## 5         55000      9             0          495000             Tunai
## 6       1800000      1             0         1800000          Transfer
## 7        120000      1            10          108000          E-Wallet
## 8         55000     10             0          550000          Transfer
## 9        650000      2             0         1300000          Transfer
## 10      4200000      3             0        12600000      Kartu Kredit
##    Segmen_Pelanggan Rating
## 1              Baru      5
## 2              Baru      4
## 3              Lama      5
## 4              Baru      5
## 5              Lama      5
## 6              Lama      5
## 7              Baru      5
## 8              Lama      3
## 9              Lama      5
## 10             Lama      5
# Memeriksa jumlah baris, struktur tipe data, dan ringkasan statistik
nrow(df_penjualan)
## [1] 300
str(df_penjualan)
## 'data.frame':    300 obs. of  13 variables:
##  $ ID_Transaksi     : chr  "TRX0001" "TRX0002" "TRX0003" "TRX0004" ...
##  $ Tanggal          : Date, format: "2025-01-01" "2025-01-01" ...
##  $ Cabang           : chr  "Jakarta" "Semarang" "Bandung" "Bandung" ...
##  $ Admin            : chr  "Maya" "Budi" "Putri" "Wawan" ...
##  $ Kategori         : chr  "Elektronik" "Alat Kantor" "Aksesori" "Elektronik" ...
##  $ Produk           : chr  "Smartwatch Fit" "Kertas A4 (Rim)" "Power Bank 20000" "Earbuds Pro" ...
##  $ Harga_Satuan     : int  1800000 55000 280000 650000 55000 1800000 120000 55000 650000 4200000 ...
##  $ Jumlah           : int  2 3 6 5 9 1 1 10 2 3 ...
##  $ Diskon_Persen    : int  0 15 5 15 0 0 10 0 0 0 ...
##  $ Total_Penjualan  : int  3600000 140250 1596000 2762500 495000 1800000 108000 550000 1300000 12600000 ...
##  $ Metode_Pembayaran: chr  "E-Wallet" "Kartu Kredit" "Tunai" "E-Wallet" ...
##  $ Segmen_Pelanggan : chr  "Baru" "Baru" "Lama" "Baru" ...
##  $ Rating           : num  5 4 5 5 5 5 5 3 5 5 ...
summary(df_penjualan)
##     ID_Transaksi    Tanggal                 Cabang          Admin    
##  Length   :300   Min.   :2025-01-01   Length   :300   Length   :300  
##  N.unique :300   1st Qu.:2025-04-12   N.unique :  4   N.unique :  9  
##  N.blank  :  0   Median :2025-06-29   N.blank  :  0   N.blank  :  0  
##  Min.nchar:  7   Mean   :2025-07-02   Min.nchar:  7   Min.nchar:  4  
##  Max.nchar:  7   3rd Qu.:2025-09-24   Max.nchar:  8   Max.nchar:  7  
##                  Max.   :2025-12-29                                  
##                                                                      
##       Kategori         Produk     Harga_Satuan         Jumlah     
##  Length   :300   Length   :300   Min.   :  55000   Min.   : 1.00  
##  N.unique :  4   N.unique : 12   1st Qu.: 240000   1st Qu.: 2.00  
##  N.blank  :  0   N.blank  :  0   Median : 650000   Median : 3.00  
##  Min.nchar:  8   Min.nchar: 11   Mean   :1502267   Mean   : 4.16  
##  Max.nchar: 11   Max.nchar: 18   3rd Qu.:1500000   3rd Qu.: 6.00  
##                                  Max.   :9500000   Max.   :10.00  
##                                                                   
##  Diskon_Persen    Total_Penjualan    Metode_Pembayaran  Segmen_Pelanggan
##  Min.   : 0.000   Min.   :   41250   Length   :300     Length   :300    
##  1st Qu.: 0.000   1st Qu.:  607750   N.unique :  4     N.unique :  2    
##  Median : 5.000   Median : 2100000   N.blank  :  0     N.blank  :  0    
##  Mean   : 8.817   Mean   : 3616210   Min.nchar:  5     Min.nchar:  4    
##  3rd Qu.:15.000   3rd Qu.: 4200000   Max.nchar: 12     Max.nchar:  4    
##  Max.   :25.000   Max.   :28500000                                      
##                                                                         
##      Rating     
##  Min.   :2.000  
##  1st Qu.:4.000  
##  Median :4.000  
##  Mean   :4.096  
##  3rd Qu.:5.000  
##  Max.   :5.000  
##  NAs    :8
# Contoh awalan filter dan agregasi (Kategori Elektronik per Cabang)
hasil_awal <- df_penjualan %>%
  filter(Kategori == "Elektronik") %>%
  group_by(Cabang) %>%
  summarise(total = sum(Total_Penjualan, na.rm = TRUE)) %>%
  arrange(desc(total))

hasil_awal
## # A tibble: 4 × 2
##   Cabang       total
##   <chr>        <int>
## 1 Surabaya 262002500
## 2 Jakarta  249015000
## 3 Semarang 192975000
## 4 Bandung  120742500

1. Produk dengan Total Penjualan Terbesar vs Jumlah Unit Terbanyak

# Ringkasan agregasi per produk
ringkasan_produk <- df_penjualan %>%
  group_by(Produk) %>%
  summarise(
    total_nilai_penjualan = sum(Total_Penjualan, na.rm = TRUE),
    total_unit_terjual    = sum(Jumlah, na.rm = TRUE),
    jumlah_transaksi      = n()
  )

# A. Produk dengan nilai Total_Penjualan paling besar
produk_omzet_terbesar <- ringkasan_produk %>%
  slice_max(total_nilai_penjualan, n = 3)

# B. Produk dengan jumlah unit (Jumlah) terjual paling banyak
produk_unit_terbanyak <- ringkasan_produk %>%
  slice_max(total_unit_terjual, n = 3)

produk_omzet_terbesar
## # A tibble: 3 × 4
##   Produk          total_nilai_penjualan total_unit_terjual jumlah_transaksi
##   <chr>                           <int>              <int>            <int>
## 1 Smartphone X5               314160000                 79               39
## 2 Laptop Ultra 14             281675000                 34               14
## 3 Earbuds Pro                 158340000                270               48
produk_unit_terbanyak
## # A tibble: 3 × 4
##   Produk            total_nilai_penjualan total_unit_terjual jumlah_transaksi
##   <chr>                             <int>              <int>            <int>
## 1 Kertas A4 (Rim)                14789500                289               50
## 2 Earbuds Pro                   158340000                270               48
## 3 Tas Ransel Laptop              47162500                146               26

2. Total Penjualan Kategori Elektronik (Diskon >= 10%) per Cabang

elektronik_diskon_cabang <- df_penjualan %>%
  filter(Kategori == "Elektronik", Diskon_Persen >= 10) %>%
  group_by(Cabang) %>%
  summarise(
    jumlah_transaksi = n(),
    total_penjualan  = sum(Total_Penjualan, na.rm = TRUE),
    rata_penjualan   = mean(Total_Penjualan, na.rm = TRUE)
  ) %>%
  arrange(desc(total_penjualan))

elektronik_diskon_cabang
## # A tibble: 4 × 4
##   Cabang   jumlah_transaksi total_penjualan rata_penjualan
##   <chr>               <int>           <int>          <dbl>
## 1 Surabaya               16       155022500       9688906.
## 2 Jakarta                14        92865000       6633214.
## 3 Semarang               15        52305000       3487000 
## 4 Bandung                 9        32017500       3557500

3. Analisis Metode Pembayaran di Cabang Jakarta

# Rekapitulasi seluruh metode pembayaran di Cabang Jakarta (Menjawab 3a & 3b)
jakarta_metode <- df_penjualan %>%
  filter(Cabang == "Jakarta") %>%
  group_by(Metode_Pembayaran) %>%
  summarise(
    jumlah_transaksi    = n(),
    rata_rata_penjualan = mean(Total_Penjualan, na.rm = TRUE),
    total_penjualan     = sum(Total_Penjualan, na.rm = TRUE)
  ) %>%
  arrange(desc(rata_rata_penjualan))

# Menampilkan tabel lengkap (3b) dan memfilter baris E-Wallet (3a)
jakarta_metode
## # A tibble: 4 × 4
##   Metode_Pembayaran jumlah_transaksi rata_rata_penjualan total_penjualan
##   <chr>                        <int>               <dbl>           <int>
## 1 Kartu Kredit                    10            4906550         49065500
## 2 E-Wallet                        38            3793776.       144163500
## 3 Transfer                        25            3194140         79853500
## 4 Tunai                           17            2838809.        48259750
jakarta_metode %>% filter(Metode_Pembayaran == "E-Wallet")
## # A tibble: 1 × 4
##   Metode_Pembayaran jumlah_transaksi rata_rata_penjualan total_penjualan
##   <chr>                        <int>               <dbl>           <int>
## 1 E-Wallet                        38            3793776.       144163500

4. Performa Admin pada Transaksi Grosir Berdiskon

admin_grosir_diskon <- df_penjualan %>%
  filter(Jumlah >= 5, Diskon_Persen > 0) %>%
  group_by(Admin) %>%
  summarise(
    total_penjualan  = sum(Total_Penjualan, na.rm = TRUE),
    jumlah_transaksi = n(),
    total_unit       = sum(Jumlah, na.rm = TRUE)
  ) %>%
  arrange(desc(total_penjualan))

# Menampilkan tabel urutan semua admin dan mengambil peringkat 1
admin_grosir_diskon
## # A tibble: 9 × 4
##   Admin   total_penjualan jumlah_transaksi total_unit
##   <chr>             <int>            <int>      <int>
## 1 Rina           24523750                9         68
## 2 Lestari        24267500                7         49
## 3 Agus           23678250                9         74
## 4 Doni           22571250                9         64
## 5 Maya           20709000                9         60
## 6 Wawan          19378750                7         48
## 7 Sari           13395500               10         73
## 8 Putri           7640500                5         37
## 9 Budi            6723750                6         42
admin_grosir_diskon %>% slice_max(total_penjualan, n = 1)
## # A tibble: 1 × 4
##   Admin total_penjualan jumlah_transaksi total_unit
##   <chr>           <int>            <int>      <int>
## 1 Rina         24523750                9         68

5. Analisis Eksplorasi Bebas (EDA) & Rekomendasi Strategis Manajemen

(i) Kebocoran Margin Akibat Diskon Tanpa Syarat Kuantitas

# Menghitung potongan diskon dan mengecek transaksi eceran (<= 2 unit) yang mendapat diskon besar (>= 10%)
evaluasi_diskon <- df_penjualan %>%
  mutate(
    Harga_Kotor     = Harga_Satuan * Jumlah,
    Nominal_Diskon  = Harga_Kotor - Total_Penjualan
  )

# Ringkasan efektivitas per tingkat diskon
ringkasan_diskon <- evaluasi_diskon %>%
  group_by(Diskon_Persen) %>%
  summarise(
    transaksi       = n(),
    rata_unit_beli  = round(mean(Jumlah), 2),
    rata_omzet_bersih = round(mean(Total_Penjualan)),
    total_potongan  = sum(Nominal_Diskon),
    rata_rating     = round(mean(Rating, na.rm = TRUE), 2)
  )

# Audit kebocoran diskon pada pembelian jumlah kecil (<= 2 unit tetapi diskon >= 10%)
kebocoran_eceran <- evaluasi_diskon %>%
  filter(Jumlah <= 2, Diskon_Persen >= 10) %>%
  group_by(Kategori) %>%
  summarise(
    jumlah_trx     = n(),
    total_potongan = sum(Nominal_Diskon),
    omzet_bersih   = sum(Total_Penjualan)
  )

ringkasan_diskon
## # A tibble: 6 × 6
##   Diskon_Persen transaksi rata_unit_beli rata_omzet_bersih total_potongan
##           <int>     <int>          <dbl>             <dbl>          <int>
## 1             0       122           3.99           4411352              0
## 2             5        37           4.59           2764628        5383750
## 3            10        36           4.5            3049625       12198500
## 4            15        40           4.12           2697475       19041000
## 5            20        25           3.88           3080800       19255000
## 6            25        40           4.18           3742031       49893750
## # ℹ 1 more variable: rata_rating <dbl>
kebocoran_eceran
## # A tibble: 4 × 4
##   Kategori    jumlah_trx total_potongan omzet_bersih
##   <chr>            <int>          <int>        <int>
## 1 Aksesori             4         371000      1519000
## 2 Alat Kantor         15        2759750     10495250
## 3 Elektronik          24       22385000    107565000
## 4 Furnitur             7        1972500     10177500

(ii) Risiko Ketergantungan Portofolio dan Masalah Kualitas Layanan Alat Kantor/Furnitur

eda_kategori_cabang <- df_penjualan %>%
  group_by(Kategori) %>%
  summarise(
    transaksi    = n(),
    total_unit   = sum(Jumlah),
    total_omzet  = sum(Total_Penjualan),
    pangsa_omzet = round(sum(Total_Penjualan) / sum(df_penjualan$Total_Penjualan) * 100, 2),
    rata_rating  = round(mean(Rating, na.rm = TRUE), 2),
    rating_rendah = sum(Rating <= 3, na.rm = TRUE)
  ) %>%
  arrange(desc(total_omzet))

eda_kategori_cabang
## # A tibble: 4 × 7
##   Kategori    transaksi total_unit total_omzet pangsa_omzet rata_rating
##   <chr>           <int>      <int>       <int>        <dbl>       <dbl>
## 1 Elektronik        122        425   824735000        76.0         4.23
## 2 Furnitur           37        151   111552500        10.3         4.14
## 3 Alat Kantor        99        448    82051000         7.56        3.88
## 4 Aksesori           42        224    66524500         6.13        4.19
## # ℹ 1 more variable: rating_rendah <int>

(iii) Ketimpangan Produktivitas Admin dan Kualitas Layanan Antar-Cabang

eda_admin <- df_penjualan %>%
  group_by(Cabang, Admin) %>%
  summarise(
    transaksi      = n(),
    total_omzet    = sum(Total_Penjualan),
    aov_per_trx    = round(mean(Total_Penjualan)),
    rata_diskon    = round(mean(Diskon_Persen), 2),
    rata_rating    = round(mean(Rating, na.rm = TRUE), 2),
    .groups        = "drop"
  ) %>%
  arrange(Cabang, desc(total_omzet))

eda_admin
## # A tibble: 9 × 7
##   Cabang   Admin   transaksi total_omzet aov_per_trx rata_diskon rata_rating
##   <chr>    <chr>       <int>       <int>       <dbl>       <dbl>       <dbl>
## 1 Bandung  Wawan          31   109446500     3530532        8.87        4.29
## 2 Bandung  Putri          26    60075000     2310577        8.08        4.04
## 3 Jakarta  Maya           28   163549000     5841036        9.82        4.11
## 4 Jakarta  Doni           29    93570250     3226560        8.1         4.11
## 5 Jakarta  Sari           33    64223000     1946152       10.3         4.03
## 6 Semarang Budi           38   127323500     3350618        7.89        3.89
## 7 Semarang Rina           37   123945750     3349885       10           4.06
## 8 Surabaya Agus           36   185566750     5154632        8.75        4.25
## 9 Surabaya Lestari        42   157163250     3741982        7.74        4.1

(iv) Pola Siklus Musiman pada Arus Kas Tahunan

eda_bulanan <- df_penjualan %>%
  mutate(Bulan = format(Tanggal, "%Y-%m")) %>%
  group_by(Bulan) %>%
  summarise(
    transaksi   = n(),
    total_unit  = sum(Jumlah),
    total_omzet = sum(Total_Penjualan),
    rata_rating = round(mean(Rating, na.rm = TRUE), 2)
  )

eda_bulanan
## # A tibble: 12 × 5
##    Bulan   transaksi total_unit total_omzet rata_rating
##    <chr>       <int>      <int>       <int>       <dbl>
##  1 2025-01        24        111    79103000        4.21
##  2 2025-02        22        107    86825750        3.95
##  3 2025-03        21         74    88939750        4.05
##  4 2025-04        27        106   116030250        4.31
##  5 2025-05        26        125   134131250        4.19
##  6 2025-06        32        125    76403000        4.12
##  7 2025-07        22        103    64659750        4   
##  8 2025-08        35        145    94509250        4.06
##  9 2025-09        22         77    74597000        3.9 
## 10 2025-10        22        104    98395750        4.18
## 11 2025-11        17         62    88967500        4.06
## 12 2025-12        30        109    82300750        4.03

(v) Retensi Pelanggan Lintas Cabang

eda_segmen <- df_penjualan %>%
  group_by(Cabang, Segmen_Pelanggan) %>%
  summarise(
    transaksi    = n(),
    total_omzet  = sum(Total_Penjualan),
    rata_belanja = round(mean(Total_Penjualan)),
    rata_diskon  = round(mean(Diskon_Persen), 2),
    rata_rating  = round(mean(Rating, na.rm = TRUE), 2),
    .groups      = "drop"
  )

eda_segmen
## # A tibble: 8 × 7
##   Cabang   Segmen_Pelanggan transaksi total_omzet rata_belanja rata_diskon
##   <chr>    <chr>                <int>       <int>        <dbl>       <dbl>
## 1 Bandung  Baru                    28    90830750      3243955        9.46
## 2 Bandung  Lama                    29    78690750      2713474        7.59
## 3 Jakarta  Baru                    32   108313000      3384781        9.38
## 4 Jakarta  Lama                    58   213029250      3672918        9.48
## 5 Semarang Baru                    34   104907750      3085522       10.3 
## 6 Semarang Lama                    41   146361500      3569793        7.8 
## 7 Surabaya Baru                    31   129958250      4192202        6.61
## 8 Surabaya Lama                    47   212771750      4527059        9.26
## # ℹ 1 more variable: rata_rating <dbl>