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 dari analisis ini adalah:
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.
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
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…
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.
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
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.
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.
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.
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
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.
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
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.
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.
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>
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")
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
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.
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:
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.
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:
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.
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:
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.
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 |
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:
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.
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.