Latar Belakang

Industri kopi dan teh merupakan salah satu sektor bisnis minuman yang terus berkembang di seluruh dunia. Persaingan yang ketat menuntut perusahaan untuk memiliki pemahaman mendalam tentang performa bisnis mereka di setiap wilayah operasional. Dalam konteks ini, Coffee Chain Datasets menyediakan data transaksi penjualan produk kopi dan teh yang beroperasi di 20 negara bagian (State) Amerika Serikat selama periode 2012–2013.

Setiap State memiliki karakteristik pasar yang berbeda mulai dari daya beli konsumen, biaya operasional, hingga efektivitas strategi pemasaran. Tanpa analisis yang sistematis, manajemen sulit mengetahui State mana yang berkinerja unggul, State mana yang memerlukan perbaikan, dan State mana yang berisiko mengalami kerugian. Pengetahuan ini sangat krusial untuk pengambilan keputusan strategis seperti alokasi anggaran pemasaran, ekspansi wilayah, maupun restrukturisasi operasional.

K-Means Clustering dipilih sebagai metode analisis karena kemampuannya mengelompokkan wilayah-wilayah (State) ke dalam segmen berdasarkan kemiripan profil kinerja finansial secara menyeluruh. Dengan mengagregasi data per State terlebih dahulu, setiap State menjadi satu titik data yang merepresentasikan rata-rata kinerja finansialnya, sehingga hasil clustering dapat langsung diinterpretasikan dalam konteks strategi bisnis per wilayah.


Tujuan Penelitian

Tujuan dari analisis ini adalah:

  1. Mengagregasi data Coffee Chain per State untuk mendapatkan profil rata-rata kinerja finansial setiap wilayah.
  2. Menentukan jumlah klaster optimal menggunakan metode Elbow.
  3. Melakukan segmentasi State menggunakan algoritma K-Means Clustering berdasarkan variabel kinerja finansial.
  4. Menginterpretasikan karakteristik setiap klaster wilayah untuk menghasilkan insight bisnis.

Deskripsi Data dan Pemilihan Variabel

Dataset yang digunakan adalah Coffee Chain Datasets yang terdiri dari 4.248 observasi dan 20 variabel, mencakup transaksi produk dari 20 State di Amerika Serikat selama tahun 2012–2013.

Analisis ini menggunakan pendekatan agregasi per State, yaitu seluruh transaksi dalam satu State dirangkum menjadi satu baris data dengan nilai rata-rata. Dengan demikian, unit analisis bberupa wilayah (State), dan terdapat 20 observasi (satu per State) yang akan di-cluster.

Variabel yang digunakan dipilih berdasarkan relevansinya terhadap kinerja finansial:

Variabel Deskripsi
Sales Rata-rata total penjualan per transaksi di State tersebut, mencerminkan skala pendapatan wilayah
Profit Rata-rata keuntungan bersih per transaksi — indikator utama profitabilitas wilayah
COGS Rata-rata Cost of Goods Sold — efisiensi biaya produksi di wilayah tersebut
Margin Rata-rata laba kotor (Sales - COGS) — nilai tambah sebelum biaya operasional
Marketing Rata-rata investasi pemasaran per transaksi — mengukur intensitas promosi di wilayah tersebut
Total_Expenses Rata-rata total pengeluaran operasional — mencerminkan beban biaya keseluruhan wilayah

Variabel-variabel ini dipilih karena bersifat numerik kontinu dan secara langsung merepresentasikan dimensi kinerja finansial yang relevan untuk segmentasi wilayah. Variabel kategorikal seperti Market, Product, dan Type tidak digunakan dalam proses clustering, namun tetap dimanfaatkan untuk interpretasi hasil. Variabel budget (Budget Sales, Budget Profit, dll.) tidak diikutsertakan untuk menghindari redundansi dengan nilai aktual dan menjaga fokus pada kinerja nyata.


Persiapan Data

Instalasi dan Pemanggilan Library

library(readxl)     # Membaca file Excel
library(dplyr)      # Manipulasi data
library(tidyr)      # Reshape data
library(ggplot2)    # Visualisasi data
library(cluster)    # Silhouette analysis
library(factoextra) # Visualisasi clustering
library(corrplot)   # Matriks korelasi
library(scales)     # Format angka pada plot
library(gridExtra)  # Menyusun beberapa plot
library(ggrepel)    # Label non-overlapping pada plot

Import Data

coffee_raw <- read_excel("D:/Kuliah 4/1. Tugas SIM 2025B - Coffee Chain Datasets.xlsx")

cat("Dimensi Data Mentah:", nrow(coffee_raw), "baris x", ncol(coffee_raw), "kolom\n")
## Dimensi Data Mentah: 4248 baris x 20 kolom
cat("Jumlah State unik  :", n_distinct(coffee_raw$State), "\n\n")
## Jumlah State unik  : 20
glimpse(coffee_raw)
## Rows: 4,248
## Columns: 20
## $ `Area Code`      <dbl> 719, 970, 970, 303, 303, 720, 970, 719, 970, 719, 303…
## $ Date             <dttm> 2012-01-01, 2012-01-01, 2012-01-01, 2012-01-01, 2012…
## $ Market           <chr> "Central", "Central", "Central", "Central", "Central"…
## $ `Market Size`    <chr> "Major Market", "Major Market", "Major Market", "Majo…
## $ Product          <chr> "Amaretto", "Colombian", "Decaf Irish Cream", "Green …
## $ `Product Line`   <chr> "Beans", "Beans", "Beans", "Leaves", "Beans", "Beans"…
## $ `Product Type`   <chr> "Coffee", "Coffee", "Coffee", "Tea", "Espresso", "Esp…
## $ State            <chr> "Colorado", "Colorado", "Colorado", "Colorado", "Colo…
## $ Type             <chr> "Regular", "Regular", "Decaf", "Regular", "Regular", …
## $ `Budget COGS`    <dbl> 90, 80, 100, 30, 60, 80, 140, 50, 50, 40, 50, 150, 10…
## $ `Budget Margin`  <dbl> 130, 110, 140, 50, 90, 130, 160, 80, 70, 70, 70, 210,…
## $ `Budget Profit`  <dbl> 100, 80, 110, 30, 70, 80, 110, 20, 40, 20, 40, 130, 1…
## $ `Budget Sales`   <dbl> 220, 190, 240, 80, 150, 210, 300, 130, 120, 110, 120,…
## $ COGS             <dbl> 89, 83, 95, 44, 54, 72, 170, 63, 60, 58, 64, 144, 95,…
## $ Inventory        <dbl> 777, 623, 821, 623, 456, 558, 1091, 435, 336, 338, 96…
## $ Margin           <dbl> 130, 107, 139, 56, 80, 108, 171, 87, 80, 72, 76, 201,…
## $ Marketing        <dbl> 24, 27, 26, 14, 15, 23, 47, 57, 19, 22, 19, 47, 30, 7…
## $ Profit           <dbl> 94, 68, 101, 30, 54, 53, 99, 0, 33, 17, 36, 111, 87, …
## $ Sales            <dbl> 219, 190, 234, 100, 134, 180, 341, 150, 140, 130, 140…
## $ `Total Expenses` <dbl> 36, 39, 38, 26, 26, 55, 72, 87, 47, 55, 40, 90, 52, 1…

Agregasi Data per State

Seluruh transaksi dalam satu State dirangkum menjadi satu baris menggunakan nilai rata-rata setiap variabel finansial. Pendekatan ini memastikan setiap State memiliki bobot yang setara dalam proses clustering, tanpa dipengaruhi perbedaan jumlah transaksi antar State.

coffee_state <- coffee_raw %>%
  group_by(State) %>%
  summarise(
    n_transaksi    = n(),
    Sales          = mean(Sales),
    Profit         = mean(Profit),
    COGS           = mean(COGS),
    Margin         = mean(Margin),
    Marketing      = mean(Marketing),
    Total_Expenses = mean(`Total Expenses`),
    .groups = "drop"
  )

cat("Dimensi Data Agregat:", nrow(coffee_state), "State x",
    ncol(coffee_state), "variabel\n\n")
## Dimensi Data Agregat: 20 State x 8 variabel
print(coffee_state %>% mutate(across(where(is.numeric), ~round(.x, 2))))
## # A tibble: 20 × 8
##    State         n_transaksi Sales Profit  COGS Margin Marketing Total_Expenses
##    <chr>               <dbl> <dbl>  <dbl> <dbl>  <dbl>     <dbl>          <dbl>
##  1 California            288 336.  110.   158.   172.       55.8           80.6
##  2 Colorado              264 182.   67.2   77.3  101.       25.8           46  
##  3 Connecticut           168 151.   45.4   62.3   85.4      24.9           48.2
##  4 Florida               216 173.   57.0   71.7   98.1      29.1           51.0
##  5 Illinois              216 324.  143.   136.   180.       41.5           63.2
##  6 Iowa                  216 253.  103.   109.   139.       35.2           54.8
##  7 Louisiana             168 138.   43.8   55.9   78.8      22.6           42.8
##  8 Massachusetts         144 208.  114.    63.0  141.       23.8           47.0
##  9 Missouri              216 114.   16.7   52.9   58.7      20.0           44.6
## 10 Nevada                264 228.   40.2  119.   102.       45.7           70.4
## 11 New Hampshire         168  88.6  16.4   33.7   53.1      14.9           39.3
## 12 New Mexico            168  94.6   4.76  45.2   47.5      18.1           43.1
## 13 New York              192 369.  105.   183.   178.       67.9           91.9
## 14 Ohio                  216 160.   49.9   67.7   88.5      23.9           47.5
## 15 Oklahoma              168 163.   50.9   66.9   93.1      29.7           51.0
## 16 Oregon                264 155.   47.1   65.5   86.0      22.8           47.2
## 17 Texas                 168 223.   93.8   93.3  125.       28.2           47.6
## 18 Utah                  288 123.   26.9   54.7   65.4      19.7           43.1
## 19 Washington            240 162.   47.5   65.9   92.7      30.2           53.5
## 20 Wisconsin             216 153.   40.3   63.2   86.6      30.3           53.3

Interpretasi: Data agregat menunjukkan variasi yang cukup besar antar State. Sebagai contoh, rata-rata Sales di New York sebesar $369 hampir empat kali lipat dibandingkan New Hampshire sebesar $89. Demikian pula Profit berkisar dari $5 di New Mexico hingga $143 di Illinois. Heterogenitas ini mengindikasikan adanya segmen wilayah yang berbeda.


Eksplorasi Data (EDA)

Statistik Deskriptif

coffee_state %>%
  select(-State, -n_transaksi) %>%
  summary()
##      Sales            Profit             COGS            Margin      
##  Min.   : 88.61   Min.   :  4.756   Min.   : 33.68   Min.   : 47.49  
##  1st Qu.:147.99   1st Qu.: 40.268   1st Qu.: 60.73   1st Qu.: 83.76  
##  Median :162.84   Median : 48.698   Median : 66.38   Median : 92.94  
##  Mean   :189.99   Mean   : 61.129   Mean   : 82.24   Mean   :103.58  
##  3rd Qu.:223.98   3rd Qu.: 96.092   3rd Qu.: 97.19   3rd Qu.:128.26  
##  Max.   :369.02   Max.   :142.690   Max.   :183.15   Max.   :180.34  
##    Marketing     Total_Expenses 
##  Min.   :14.92   Min.   :39.32  
##  1st Qu.:22.76   1st Qu.:45.66  
##  Median :27.02   Median :47.90  
##  Mean   :30.50   Mean   :53.30  
##  3rd Qu.:31.54   3rd Qu.:53.85  
##  Max.   :67.94   Max.   :91.86

Visualisasi Distribusi Variabel per State

coffee_state_long <- coffee_state %>%
  select(-n_transaksi) %>%
  pivot_longer(-State, names_to = "Variabel", values_to = "Nilai")

ggplot(coffee_state_long, aes(x = reorder(State, Nilai), y = Nilai, fill = Variabel)) +
  geom_col(show.legend = FALSE) +
  coord_flip() +
  facet_wrap(~Variabel, scales = "free_x", ncol = 3) +
  scale_fill_brewer(palette = "Set2") +
  labs(
    title    = "Profil Kinerja Finansial per State",
    subtitle = "Nilai rata-rata setiap variabel finansial di 20 State",
    x = "State", y = "Nilai Rata-rata ($)"
  ) +
  theme_minimal(base_size = 10) +
  theme(plot.title = element_text(face = "bold"))

Interpretasi: Terlihat jelas bahwa State seperti New York, California, dan Illinois mendominasi pada setiap variabel finansial, sementara New Mexico, New Hampshire, dan Missouri berada di posisi terbawah. Pola ini konsisten di hampir semua variabel, mengindikasikan adanya pengelompokan alami yang akan ditangkap oleh algoritma K-Means nantinya.

Matriks Korelasi Antar Variabel

cor_mat <- coffee_state %>%
  select(Sales, Profit, COGS, Margin, Marketing, Total_Expenses) %>%
  cor()

corrplot(cor_mat,
         method   = "color",
         type     = "upper",
         addCoef.col = "black",
         number.cex  = 0.85,
         tl.col   = "black",
         tl.srt   = 45,
         col      = colorRampPalette(c("#d73027","white","#1a9641"))(200),
         title    = "Matriks Korelasi Variabel Finansial",
         mar      = c(0,0,2,0))

Interpretasi: Dapat dilihat bahwa korelasi antar variabel sangat tinggi ( lebih dari 0.85), hal ini wajar karena semua variabel merupakan turunan dari aktivitas penjualan yang sama. Meski demikian, setiap variabel tetap memberikan perspektif yang berbeda misalnya, dua State dengan Sales serupa bisa memiliki Profit yang sangat berbeda karena perbedaan COGS atau Marketing. Oleh karena itu, keenam variabel tetap dipertahankan dan standardisasi menjadi sangat penting untuk menyeimbangkan pengaruh dari masing-masing variabel.

Scatter Plot Sales vs Profit per State

ggplot(coffee_state, aes(x = Sales, y = Profit, label = State)) +
  geom_point(aes(size = Marketing), color = "#6B4226", alpha = 0.75) +
  geom_text_repel(size = 3, max.overlaps = 20) +
  scale_size_continuous(range = c(3, 10)) +
  labs(
    title    = "Hubungan Sales vs Profit per State",
    subtitle = "Ukuran titik mencerminkan rata-rata biaya Marketing",
    x        = "Rata-rata Sales ($)",
    y        = "Rata-rata Profit ($)",
    size     = "Marketing ($)"
  ) +
  theme_minimal(base_size = 11) +
  theme(plot.title = element_text(face = "bold"))

Interpretasi: Scatter plot memperlihatkan tiga kelompok State yang mulai tampak secara visual: kelompok kanan-atas (Sales dan Profit tinggi seperti New York, California, Illinois), kelompok tengah (performa sedang), dan kelompok kiri-bawah (Sales dan Profit rendah seperti New Hampshire, New Mexico). Pola inilah yang akan dikonfirmasi secara statistik melalui K-Means.


Preprocessing: Standardisasi Data

K-Means menggunakan jarak Euclidean, sehingga variabel dengan skala besar akan mendominasi perhitungan jarak. Standardisasi Z-score memastikan setiap variabel memiliki pengaruh setara dengan mean = 0 dan standar deviasi = 1.

coffee_num <- coffee_state %>%
  select(Sales, Profit, COGS, Margin, Marketing, Total_Expenses)

coffee_scaled <- scale(coffee_num)
rownames(coffee_scaled) <- coffee_state$State

cat("Mean setelah standardisasi:\n")
## Mean setelah standardisasi:
round(colMeans(coffee_scaled), 6)
##          Sales         Profit           COGS         Margin      Marketing 
##              0              0              0              0              0 
## Total_Expenses 
##              0
cat("\nStandar Deviasi setelah standardisasi:\n")
## 
## Standar Deviasi setelah standardisasi:
round(apply(coffee_scaled, 2, sd), 6)
##          Sales         Profit           COGS         Margin      Marketing 
##              1              1              1              1              1 
## Total_Expenses 
##              1
as.data.frame(coffee_scaled) %>%
  round(3) %>%
  tibble::rownames_to_column("State")
##            State  Sales Profit   COGS Margin Marketing Total_Expenses
## 1     California  1.863  1.306  1.926  1.700     1.915          2.028
## 2       Colorado -0.095  0.161 -0.126 -0.060    -0.357         -0.542
## 3    Connecticut -0.492 -0.418 -0.507 -0.454    -0.426         -0.379
## 4        Florida -0.212 -0.110 -0.267 -0.137    -0.107         -0.173
## 5       Illinois  1.699  2.163  1.380  1.920     0.833          0.735
## 6           Iowa  0.808  1.106  0.678  0.892     0.353          0.112
## 7      Louisiana -0.663 -0.460 -0.669 -0.620    -0.602         -0.783
## 8  Massachusetts  0.230  1.407 -0.491  0.926    -0.508         -0.469
## 9       Missouri -0.966 -1.179 -0.746 -1.123    -0.793         -0.643
## 10        Nevada  0.482 -0.555  0.939 -0.046     1.149          1.269
## 11 New Hampshire -1.290 -1.187 -1.236 -1.262    -1.181         -1.037
## 12    New Mexico -1.214 -1.495 -0.942 -1.403    -0.940         -0.756
## 13      New York  2.278  1.155  2.568  1.869     2.837          2.861
## 14          Ohio -0.384 -0.298 -0.369 -0.377    -0.499         -0.434
## 15      Oklahoma -0.337 -0.270 -0.391 -0.261    -0.063         -0.167
## 16        Oregon -0.446 -0.372 -0.426 -0.441    -0.582         -0.456
## 17         Texas  0.416  0.868  0.281  0.526    -0.171         -0.422
## 18          Utah -0.854 -0.907 -0.700 -0.954    -0.820         -0.758
## 19    Washington -0.354 -0.361 -0.416 -0.271    -0.024          0.017
## 20     Wisconsin -0.469 -0.553 -0.486 -0.423    -0.013         -0.002

Penentuan Jumlah Klaster Optimal

Metode Elbow

Setelah prosedur standarisasi dilakukan tahap selanjutnya adalah penentuan K optimal. Metode pertma yang dilakukan adalah metode elbow. Metode Elbow mengevaluasi Within-Cluster Sum of Squares (WSS) untuk k = 1 hingga 10. Titik “siku” adalah nilai k di mana penurunan WSS mulai melambat secara signifikan.

set.seed(123)

fviz_nbclust(
  coffee_scaled, kmeans,
  method   = "wss",
  k.max    = 10,
  linecolor = "#6B4226"
) +
  geom_vline(xintercept = 3, linetype = "dashed",
             color = "red", linewidth = 0.8) +
  labs(
    title    = "Metode Elbow - Penentuan Jumlah Klaster Optimal",
    x        = "Jumlah Klaster (k)",
    y        = "Total Within-Cluster Sum of Squares (WSS)"
  ) +
  theme_minimal(base_size = 11) +
  theme(plot.title = element_text(face = "bold"))

Interpretasi: Penurunan WSS paling tajam terjadi dari k=1 ke k=3. Setelah k=3, kurva mulai mendatar, menandakan bahwa penambahan klaster tidak lagi memberikan peningkatan pemisahan yang berarti. sehingga k = 3 diidentifikasi sebagai titik siku yang optimal.


K-Means Clustering dengan k = 3

Menjalankan Algoritma K-Means

set.seed(123)

km_result <- kmeans(
  coffee_scaled,
  centers  = 3,
  nstart   = 25,
  iter.max = 100
)

cat("=== Hasil K-Means Clustering (k = 3) ===\n\n")
## === Hasil K-Means Clustering (k = 3) ===
cat("Ukuran setiap klaster:\n")
## Ukuran setiap klaster:
print(km_result$size)
## [1]  4  3 13
cat("\nVariabilitas yang dijelaskan (BSS/TSS):",
    round(km_result$betweenss / km_result$totss * 100, 2), "%\n")
## 
## Variabilitas yang dijelaskan (BSS/TSS): 78.64 %
coffee_result <- coffee_state %>%
  mutate(Klaster = factor(km_result$cluster))

# ── Re-label: pastikan Klaster 1=Rendah, 2=Menengah, 3=Tinggi ──
rank_klaster <- coffee_result %>%
  group_by(Klaster) %>%
  summarise(avg_profit = mean(Profit), .groups = "drop") %>%
  arrange(avg_profit) %>%
  mutate(Klaster_Baru = factor(row_number()))   # 1=rendah → 3=tinggi

coffee_result <- coffee_result %>%
  left_join(rank_klaster %>% select(Klaster, Klaster_Baru), by = "Klaster") %>%
  mutate(Klaster = Klaster_Baru) %>%
  select(-Klaster_Baru)
# ────────────────────────────────────────────────────────────────

coffee_result %>%
  select(State, Klaster, Sales, Profit, COGS, Marketing, Total_Expenses) %>%
  arrange(Klaster, desc(Profit)) %>%
  mutate(across(where(is.numeric), ~round(.x, 1)))
## # A tibble: 20 × 7
##    State         Klaster Sales Profit  COGS Marketing Total_Expenses
##    <chr>         <fct>   <dbl>  <dbl> <dbl>     <dbl>          <dbl>
##  1 Colorado      1       182.    67.2  77.3      25.8           46  
##  2 Florida       1       173.    57    71.7      29.1           51  
##  3 Oklahoma      1       164.    50.9  66.9      29.7           51.1
##  4 Ohio          1       160.    49.9  67.7      23.9           47.5
##  5 Washington    1       162.    47.5  65.9      30.2           53.5
##  6 Oregon        1       155.    47.1  65.5      22.8           47.2
##  7 Connecticut   1       151.    45.4  62.3      24.9           48.2
##  8 Louisiana     1       138.    43.8  55.9      22.6           42.8
##  9 Wisconsin     1       153.    40.3  63.1      30.3           53.3
## 10 Utah          1       123.    26.9  54.7      19.7           43.1
## 11 Missouri      1       114.    16.7  52.9      20             44.6
## 12 New Hampshire 1        88.6   16.4  33.7      14.9           39.3
## 13 New Mexico    1        94.6    4.8  45.2      18.1           43.1
## 14 Massachusetts 2       208.   114.   63        23.8           47  
## 15 Iowa          2       254.   103.  109.       35.2           54.8
## 16 Texas         2       223.    93.8  93.3      28.2           47.6
## 17 Nevada        2       228.    40.2 119.       45.7           70.4
## 18 Illinois      3       324.   143.  136.       41.5           63.2
## 19 California    3       336.   110.  158.       55.8           80.6
## 20 New York      3       369    105.  183.       67.9           91.9

Visualisasi Klaster - PCA Biplot

Karena data memiliki 6 dimensi, Principal Component Analysis (PCA) digunakan untuk memproyeksikan data ke 2 dimensi agar klaster dapat divisualisasikan. Label State ditampilkan langsung pada plot.

km_plot <- km_result
km_plot$cluster <- as.integer(coffee_result$Klaster)

fviz_cluster(
  km_plot,
  data          = coffee_scaled,
  geom          = "text",
  repel         = TRUE,
  ellipse.type  = "convex",
  palette       = c("#E74C3C","#2ECC71","#3498DB"),
  ggtheme       = theme_minimal(base_size = 11),
  labelsize     = 9
) +
  labs(
    title    = "K-Means Clustering State Coffee Chain (k = 3)",
    subtitle = "Proyeksi PCA 2 Dimensi - setiap titik merepresentasikan satu State"
  ) +
  theme(plot.title = element_text(face = "bold"))

Interpretasi: Setiap titik di dalam plot PCA tersebut menggambarkan satu state (wilayah). Plot PCA memperlihatkan tiga klaster yang terpisah dengan jelas menunjukkan bahwa State dalam klaster yang sama memiliki profil kinerja finansial yang serupa. Pemisahan yang bersih antar klaster mengindikasikan kualitas clustering yang baik.

Peta Kinerja State (wilayah) Berdasarkan Hasil Clustering

ggplot(coffee_result,
       aes(x = Sales, y = Profit, color = Klaster, label = State)) +
  geom_point(aes(size = Marketing), alpha = 0.85) +
  geom_text_repel(size = 3, show.legend = FALSE, max.overlaps = 20) +
  scale_color_manual(
    values = c("1" = "#E74C3C", "2" = "#2ECC71", "3" = "#3498DB"),
    labels = c("1" = "Klaster 1 - Performa Rendah",
               "2" = "Klaster 2 - Performa Menengah",
               "3" = "Klaster 3 - Performa Tinggi")
  ) +
  scale_size_continuous(range = c(3, 10)) +
  labs(
    title    = "Peta Kinerja State Berdasarkan Hasil K-Means Clustering",
    subtitle = "Sumbu X = rata-rata Sales | Sumbu Y = rata-rata Profit | Ukuran titik = Marketing",
    x        = "Rata-rata Sales ($)",
    y        = "Rata-rata Profit ($)",
    color    = "Klaster",
    size     = "Marketing ($)"
  ) +
  theme_minimal(base_size = 11) +
  theme(plot.title      = element_text(face = "bold"),
        legend.position = "bottom",
        legend.box      = "vertical")

Interpretasi: State seperti New York, California, dan Illinois berada di kuadran kanan-atas (Klaster 3 — biru), mengindikasikan performa bisnis terbaik. State seperti Massachusetts, Texas, Lowa, dan Nevada masuk ke kluster dengan performa menengah (Klaster 2 — hijau). Kemudian, New Mexico, New Hampshire, dan beberapa state lain berada di kiri-bawah (Klaster 1 — merah), menunjukkan performa yang perlu ditingkatkan secara signifikan.


Karakteristik dan Interpretasi Klaster

Profil Rata-rata Setiap Klaster

profil <- coffee_result %>%
  group_by(Klaster) %>%
  summarise(
    Jumlah_State   = n(),
    Avg_Sales      = round(mean(Sales), 1),
    Avg_Profit     = round(mean(Profit), 1),
    Avg_COGS       = round(mean(COGS), 1),
    Avg_Margin     = round(mean(Margin), 1),
    Avg_Marketing  = round(mean(Marketing), 1),
    Avg_TotExp     = round(mean(Total_Expenses), 1)
  )

print(profil)
## # A tibble: 3 × 8
##   Klaster Jumlah_State Avg_Sales Avg_Profit Avg_COGS Avg_Margin Avg_Marketing
##   <fct>          <int>     <dbl>      <dbl>    <dbl>      <dbl>         <dbl>
## 1 1                 13       143       39.5     60.2       79.6          24  
## 2 2                  4       228       87.8     96.1      126.           33.2
## 3 3                  3       343      119.     159.       177.           55.1
## # ℹ 1 more variable: Avg_TotExp <dbl>

Perbandingan Profil Klaster

profil_long <- profil %>%
  select(Klaster, Avg_Sales, Avg_Profit, Avg_COGS, Avg_Marketing, Avg_TotExp) %>%
  pivot_longer(-Klaster, names_to = "Variabel", values_to = "Nilai") %>%
  mutate(Variabel = recode(Variabel,
    "Avg_Sales"     = "Sales",
    "Avg_Profit"    = "Profit",
    "Avg_COGS"      = "COGS",
    "Avg_Marketing" = "Marketing",
    "Avg_TotExp"    = "Total Expenses"
  ))

ggplot(profil_long, aes(x = Variabel, y = Nilai, fill = Klaster)) +
  geom_col(position = "dodge", alpha = 0.85, width = 0.7) +
  geom_text(aes(label = round(Nilai, 0)),
            position = position_dodge(width = 0.7),
            vjust = -0.4, size = 3) +
  scale_fill_manual(
    values = c("1" = "#E74C3C", "2" = "#2ECC71", "3" = "#3498DB"),
    labels = c("1" = "Klaster 1", "2" = "Klaster 2", "3" = "Klaster 3")
  ) +
  labs(
    title    = "Perbandingan Profil Rata-rata Kinerja Finansial per Klaster",
    subtitle = "Setiap batang menunjukkan rata-rata variabel finansial di dalam klaster",
    x = NULL, y = "Nilai Rata-rata ($)", fill = "Klaster"
  ) +
  theme_minimal(base_size = 11) +
  theme(plot.title = element_text(face = "bold"),
        legend.position = "top")

Daftar State per Klaster

coffee_result %>%
  arrange(Klaster, desc(Profit)) %>%
  select(Klaster, State, Sales, Profit, COGS, Marketing, Total_Expenses) %>%
  mutate(across(where(is.numeric), ~round(.x, 1)))
## # A tibble: 20 × 7
##    Klaster State         Sales Profit  COGS Marketing Total_Expenses
##    <fct>   <chr>         <dbl>  <dbl> <dbl>     <dbl>          <dbl>
##  1 1       Colorado      182.    67.2  77.3      25.8           46  
##  2 1       Florida       173.    57    71.7      29.1           51  
##  3 1       Oklahoma      164.    50.9  66.9      29.7           51.1
##  4 1       Ohio          160.    49.9  67.7      23.9           47.5
##  5 1       Washington    162.    47.5  65.9      30.2           53.5
##  6 1       Oregon        155.    47.1  65.5      22.8           47.2
##  7 1       Connecticut   151.    45.4  62.3      24.9           48.2
##  8 1       Louisiana     138.    43.8  55.9      22.6           42.8
##  9 1       Wisconsin     153.    40.3  63.1      30.3           53.3
## 10 1       Utah          123.    26.9  54.7      19.7           43.1
## 11 1       Missouri      114.    16.7  52.9      20             44.6
## 12 1       New Hampshire  88.6   16.4  33.7      14.9           39.3
## 13 1       New Mexico     94.6    4.8  45.2      18.1           43.1
## 14 2       Massachusetts 208.   114.   63        23.8           47  
## 15 2       Iowa          254.   103.  109.       35.2           54.8
## 16 2       Texas         223.    93.8  93.3      28.2           47.6
## 17 2       Nevada        228.    40.2 119.       45.7           70.4
## 18 3       Illinois      324.   143.  136.       41.5           63.2
## 19 3       California    336.   110.  158.       55.8           80.6
## 20 3       New York      369    105.  183.       67.9           91.9

Silhouette Plot - Validasi Kualitas Clustering

sil <- silhouette(km_result$cluster, dist(coffee_scaled))

fviz_silhouette(sil,
  palette  = c("#E74C3C","#2ECC71","#3498DB"),
  ggtheme  = theme_minimal(base_size = 11)
) +
  labs(
    title    = "Silhouette Plot - Validasi Kualitas K-Means Clustering"
  ) +
  theme(plot.title = element_text(face = "bold"))
##   cluster size ave.sil.width
## 1       1    4          0.26
## 2       2    3          0.39
## 3       3   13          0.57

cat("Rata-rata Silhouette Width keseluruhan:",
    round(mean(sil[, "sil_width"]), 4), "\n\n")
## Rata-rata Silhouette Width keseluruhan: 0.4835
as.data.frame(sil) %>%
  mutate(State = coffee_state$State) %>%
  select(State, cluster, neighbor, sil_width) %>%
  arrange(cluster, desc(sil_width)) %>%
  mutate(across(where(is.numeric), ~round(.x, 3)))
##            State cluster neighbor sil_width
## 1           Iowa       1        3     0.452
## 2          Texas       1        3     0.303
## 3  Massachusetts       1        3     0.215
## 4         Nevada       1        3     0.076
## 5     California       2        1     0.539
## 6       New York       2        1     0.524
## 7       Illinois       2        1     0.099
## 8    Connecticut       3        1     0.668
## 9           Utah       3        1     0.665
## 10     Louisiana       3        1     0.664
## 11        Oregon       3        1     0.655
## 12      Missouri       3        1     0.646
## 13          Ohio       3        1     0.630
## 14    New Mexico       3        1     0.587
## 15     Wisconsin       3        1     0.576
## 16 New Hampshire       3        1     0.574
## 17      Oklahoma       3        1     0.544
## 18    Washington       3        1     0.525
## 19       Florida       3        1     0.435
## 20      Colorado       3        1     0.294

Interpretasi: Nilai rata-rata silhouette yang positif mengkonfirmasi bahwa pengelompokan cukup baik. Sebagian besar State berada di klaster yang paling sesuai dengan profilnya. State dengan nilai silhouette mendekati 0 merupakan kasus perbatasan (borderline) yang memiliki karakteristik campuran antara dua klaster.


Interpretasi Hasil Clustering per Klaster

Klaster 1 - “Wilayah Berkembang” (Performa Rendah)

coffee_result %>%
  filter(Klaster == 1) %>%
  select(State, Sales, Profit, COGS, Marketing, Total_Expenses) %>%
  mutate(across(where(is.numeric), ~round(.x, 1))) %>%
  arrange(desc(Profit))
## # A tibble: 13 × 6
##    State         Sales Profit  COGS Marketing Total_Expenses
##    <chr>         <dbl>  <dbl> <dbl>     <dbl>          <dbl>
##  1 Colorado      182.    67.2  77.3      25.8           46  
##  2 Florida       173.    57    71.7      29.1           51  
##  3 Oklahoma      164.    50.9  66.9      29.7           51.1
##  4 Ohio          160.    49.9  67.7      23.9           47.5
##  5 Washington    162.    47.5  65.9      30.2           53.5
##  6 Oregon        155.    47.1  65.5      22.8           47.2
##  7 Connecticut   151.    45.4  62.3      24.9           48.2
##  8 Louisiana     138.    43.8  55.9      22.6           42.8
##  9 Wisconsin     153.    40.3  63.1      30.3           53.3
## 10 Utah          123.    26.9  54.7      19.7           43.1
## 11 Missouri      114.    16.7  52.9      20             44.6
## 12 New Hampshire  88.6   16.4  33.7      14.9           39.3
## 13 New Mexico     94.6    4.8  45.2      18.1           43.1

Karakteristik:

  • Sales rendah — rata-rata penjualan paling kecil dibanding klaster lain
  • Profit paling tipis — margin keuntungan sangat kecil, beberapa State hampir impas
  • COGS dan Total Expenses relatif tinggi terhadap Sales — efisiensi biaya rendah
  • Marketing rendah — investasi pada promosi masih minimal, kemungkinan pasar yang belum matang

Rekomendasi: Evaluasi apakah operasional di State ini layak dilanjutkan. Jika pasar memiliki potensi jangka panjang, pertimbangkan investasi bertahap untuk membangun pangsa pasar. Fokus pada efisiensi COGS dan pengurangan biaya operasional sebagai prioritas utama.

Klaster 2 - “Wilayah Stabil” (Performa Menengah)

coffee_result %>%
  filter(Klaster == 2) %>%
  select(State, Sales, Profit, COGS, Marketing, Total_Expenses) %>%
  mutate(across(where(is.numeric), ~round(.x, 1))) %>%
  arrange(desc(Profit))
## # A tibble: 4 × 6
##   State         Sales Profit  COGS Marketing Total_Expenses
##   <chr>         <dbl>  <dbl> <dbl>     <dbl>          <dbl>
## 1 Massachusetts  208.  114.   63        23.8           47  
## 2 Iowa           254.  103.  109.       35.2           54.8
## 3 Texas          223.   93.8  93.3      28.2           47.6
## 4 Nevada         228.   40.2 119.       45.7           70.4

Karakteristik:

  • Sales dan Profit menengah — performa stabil, tidak menonjol namun konsisten
  • COGS moderat — efisiensi biaya cukup baik
  • Marketing proporsional — investasi pemasaran seimbang dengan hasil yang diperoleh
  • Total Expenses terkendali — struktur biaya relatif efisien

Rekomendasi: Klaster memiliki state dengan fondasi yang kuat dan potensi untuk naik ke Klaster 3. Strategi yang tepat adalah meningkatkan anggaran marketing secara terukur dan mengoptimalkan portofolio produk untuk mendorong pertumbuhan Sales dan Profit.

Klaster 3 - “Wilayah Unggulan” (Performa Tinggi)

coffee_result %>%
  filter(Klaster == 3) %>%
  select(State, Sales, Profit, COGS, Marketing, Total_Expenses) %>%
  mutate(across(where(is.numeric), ~round(.x, 1))) %>%
  arrange(desc(Profit))
## # A tibble: 3 × 6
##   State      Sales Profit  COGS Marketing Total_Expenses
##   <chr>      <dbl>  <dbl> <dbl>     <dbl>          <dbl>
## 1 Illinois    324.   143.  136.      41.5           63.2
## 2 California  336.   110.  158.      55.8           80.6
## 3 New York    369    105.  183.      67.9           91.9

Karakteristik:

  • Sales tertinggi — pendapatan penjualan jauh di atas rata-rata nasional
  • Profit tertinggi — menghasilkan keuntungan bersih yang signifikan
  • Marketing tinggi namun efektif — pemasaran baik, investasi menghasilkan penjualan yang proporsional
  • Margin tinggi — produk terjual dengan nilai tambah yang besar

Rekomendasi: Pertahankan dan perkuat posisi di State ini. Jadikan sebagai benchmark (tolak ukur) strategi operasional dan pemasaran untuk diterapkan di State lain. Manajemen juga dapat mempertimbangkan ekspansi varian produk premium di wilayah-wilayah ini.


Rekomendasi Untuk Bisnis

Berdasarkan hasil segmentasi wilayah menggunakan K-Means Clustering, berikut rekomendasi strategis untuk manajemen Coffee Chain:

Prioritas Klaster Aksi Strategis
Segera Klaster 1 - Berkembang Audit biaya operasional; pertimbangkan restrukturisasi atau divestasi di State yang terus merugi
Jangka Menengah Klaster 2 - Stabil Tingkatkan investasi pemasaran secara bertahap; optimalkan portofolio produk untuk mendorong pertumbuhan
Pertahankan Klaster 3 - Unggulan Pertahankan strategi yang sudah terbukti; ekspansi produk premium; jadikan tolak ukur nasional

Kesimpulan

Analisis K-Means Clustering dengan k = 3 berhasil mengelompokkan 20 State operasional Coffee Chain ke dalam tiga segmen wilayah yang memiliki karakteristik kinerja finansial yang berbeda:

  • Klaster 1 - Wilayah Berkembang: State dengan Sales, Profit, dan efisiensi biaya yang rendah. Memerlukan evaluasi strategis mendasar.
  • Klaster 2 - Wilayah Stabil: State dengan kinerja menengah yang konsisten. Berpotensi untuk ditingkatkan ke performa lebih tinggi.
  • Klaster 3 - Wilayah Unggulan: State dengan Sales dan Profit tertinggi. Menjadi basis utama bisnis Coffee Chain dan referensi strategi terbaik.

Metode Elbow mengkonfirmasi k = 3 sebagai jumlah klaster optimal, dan nilai silhouette yang positif mengindikasikan kualitas pengelompokan yang baik. Pendekatan agregasi per State memberikan hasil yang lebih actionable secara bisnis dibandingkan clustering per transaksi, karena manajemen dapat langsung mengidentifikasi wilayah mana yang sudah optimal dan wilayah mana yang perlu mendapat perhatian khusus.

Rekomendasi Untuk Penelitian Selanjutnya

Pada penelitian ini hanya menggunakan metode elbow dalam penentuan k optimal. Penelitian selanjutnya dapat menggunakan metode lain seperti metode silhouette untuk mengkonfirmasi nilai k optimal yang akan digunakan dalam analisis K-means clustering.