Coffee Chain merupakan perusahaan jaringan kopi yang beroperasi di berbagai wilayah di Amerika Serikat. Dalam era persaingan bisnis yang semakin ketat, kemampuan untuk menganalisis data penjualan secara kuantitatif menjadi keunggulan kompetitif yang krusial. Data transaksi yang dikumpulkan selama periode 2012–2013 mencakup berbagai dimensi operasional, mulai dari performa produk, distribusi geografis, hingga efisiensi anggaran.
Analisis data diperlukan untuk memahami pola penjualan (sales), profitabilitas (profit), serta faktor-faktor yang memengaruhinya. Dengan pendekatan statistik yang tepat, manajemen dapat membuat keputusan berbasis data (data-driven decision making) yang lebih akurat dan efektif.
Laporan ini bertujuan untuk:
Data yang digunakan adalah dataset Coffee Chain yang terdiri dari 4.248 observasi dengan 20 variabel, mencakup periode Januari 2012 hingga Desember 2013. Dataset mencakup informasi produk, lokasi, anggaran, biaya, dan kinerja keuangan dari jaringan kopi tersebut.
Tahap pertama adalah memuat data dari file Excel dan melakukan standarisasi nama kolom agar dapat diproses dengan baik di lingkungan R.
library(readxl)
library(dplyr)
library(tidyr)
library(ggplot2)
library(lubridate)
library(scales)
library(plotly)
library(forecast)
library(FSA)
library(cluster)
library(factoextra)
library(knitr)
library(kableExtra)
library(gridExtra)
library(usmap)
df_raw <- read_excel("C:/Users/ADVAN/Downloads/1. Tugas SIM 2025B - Coffee Chain Datasets/1. Tugas SIM 2025B - Coffee Chain Datasets.xlsx", sheet = "data")
# Standarisasi nama kolom: spasi diganti titik
df <- df_raw
colnames(df) <- make.names(colnames(df))
# Konversi tipe data
df$Date <- as.Date(df$Date)
df$Product.Type <- as.factor(df$Product.Type)
df$State <- as.factor(df$State)
df$Market <- as.factor(df$Market)
df$Market.Size <- as.factor(df$Market.Size)
df$Type <- as.factor(df$Type)
df$Product.Line <- as.factor(df$Product.Line)
# Ekstrak komponen waktu
df$Tahun <- year(df$Date)
df$Bulan <- month(df$Date)
df$YearMo <- floor_date(df$Date, "month")
glimpse(df)
## Rows: 4,248
## Columns: 23
## $ Area.Code <dbl> 719, 970, 970, 303, 303, 720, 970, 719, 970, 719, 303, …
## $ Date <date> 2012-01-01, 2012-01-01, 2012-01-01, 2012-01-01, 2012-0…
## $ Market <fct> Central, Central, Central, Central, Central, Central, C…
## $ Market.Size <fct> Major Market, Major Market, Major Market, Major Market,…
## $ Product <chr> "Amaretto", "Colombian", "Decaf Irish Cream", "Green Te…
## $ Product.Line <fct> Beans, Beans, Beans, Leaves, Beans, Beans, Leaves, Leav…
## $ Product.Type <fct> Coffee, Coffee, Coffee, Tea, Espresso, Espresso, Herbal…
## $ State <fct> Colorado, Colorado, Colorado, Colorado, Colorado, Color…
## $ Type <fct> Regular, Regular, Decaf, Regular, Regular, Decaf, Decaf…
## $ Budget.COGS <dbl> 90, 80, 100, 30, 60, 80, 140, 50, 50, 40, 50, 150, 100,…
## $ Budget.Margin <dbl> 130, 110, 140, 50, 90, 130, 160, 80, 70, 70, 70, 210, 1…
## $ Budget.Profit <dbl> 100, 80, 110, 30, 70, 80, 110, 20, 40, 20, 40, 130, 100…
## $ Budget.Sales <dbl> 220, 190, 240, 80, 150, 210, 300, 130, 120, 110, 120, 3…
## $ COGS <dbl> 89, 83, 95, 44, 54, 72, 170, 63, 60, 58, 64, 144, 95, 2…
## $ Inventory <dbl> 777, 623, 821, 623, 456, 558, 1091, 435, 336, 338, 965,…
## $ Margin <dbl> 130, 107, 139, 56, 80, 108, 171, 87, 80, 72, 76, 201, 1…
## $ Marketing <dbl> 24, 27, 26, 14, 15, 23, 47, 57, 19, 22, 19, 47, 30, 77,…
## $ Profit <dbl> 94, 68, 101, 30, 54, 53, 99, 0, 33, 17, 36, 111, 87, 20…
## $ 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, 109…
## $ Tahun <dbl> 2012, 2012, 2012, 2012, 2012, 2012, 2012, 2012, 2012, 2…
## $ Bulan <dbl> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1…
## $ YearMo <date> 2012-01-01, 2012-01-01, 2012-01-01, 2012-01-01, 2012-0…
Statistik deskriptif memberikan gambaran ringkas mengenai sebaran nilai setiap variabel numerik, meliputi nilai minimum, kuartil, rata-rata, dan maksimum.
var_numerik <- df %>%
select(Sales, Profit, COGS, Margin, Marketing, Inventory,
Total.Expenses, Budget.Sales, Budget.Profit,
Budget.COGS, Budget.Margin)
summary(var_numerik) %>%
kable(caption = "Statistik Deskriptif Variabel Numerik") %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed"))
| Sales | Profit | COGS | Margin | Marketing | Inventory | Total.Expenses | Budget.Sales | Budget.Profit | Budget.COGS | Budget.Margin | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| Min. : 17 | Min. :-638.0 | Min. : 0.00 | Min. :-302.00 | Min. : 0.00 | Min. :-3534.0 | Min. : 10.00 | Min. : 0.0 | Min. :-320.00 | Min. : 0.00 | Min. :-210.0 | |
| 1st Qu.:100 | 1st Qu.: 17.0 | 1st Qu.: 43.00 | 1st Qu.: 52.75 | 1st Qu.: 13.00 | 1st Qu.: 432.0 | 1st Qu.: 33.00 | 1st Qu.: 80.0 | 1st Qu.: 20.00 | 1st Qu.: 30.00 | 1st Qu.: 50.0 | |
| Median :138 | Median : 40.0 | Median : 60.00 | Median : 76.00 | Median : 22.00 | Median : 619.0 | Median : 46.00 | Median : 130.0 | Median : 40.00 | Median : 50.00 | Median : 70.0 | |
| Mean :193 | Mean : 61.1 | Mean : 84.43 | Mean : 104.29 | Mean : 31.19 | Mean : 749.4 | Mean : 54.06 | Mean : 175.6 | Mean : 60.91 | Mean : 74.83 | Mean : 100.8 | |
| 3rd Qu.:230 | 3rd Qu.: 92.0 | 3rd Qu.:100.00 | 3rd Qu.: 132.00 | 3rd Qu.: 39.00 | 3rd Qu.: 910.5 | 3rd Qu.: 65.00 | 3rd Qu.: 210.0 | 3rd Qu.: 80.00 | 3rd Qu.: 90.00 | 3rd Qu.: 130.0 | |
| Max. :912 | Max. : 778.0 | Max. :364.00 | Max. : 613.00 | Max. :156.00 | Max. : 8252.0 | Max. :190.00 | Max. :1140.0 | Max. : 560.00 | Max. :450.00 | Max. : 690.0 |
data.frame(
Variabel = names(df),
Tipe = sapply(df, class),
Nilai_Hilang = colSums(is.na(df))
) %>%
kable(caption = "Rekap Nilai Hilang per Variabel", row.names = FALSE) %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed"))
| Variabel | Tipe | Nilai_Hilang |
|---|---|---|
| Area.Code | numeric | 0 |
| Date | Date | 0 |
| Market | factor | 0 |
| Market.Size | factor | 0 |
| Product | character | 0 |
| Product.Line | factor | 0 |
| Product.Type | factor | 0 |
| State | factor | 0 |
| Type | factor | 0 |
| Budget.COGS | numeric | 0 |
| Budget.Margin | numeric | 0 |
| Budget.Profit | numeric | 0 |
| Budget.Sales | numeric | 0 |
| COGS | numeric | 0 |
| Inventory | numeric | 0 |
| Margin | numeric | 0 |
| Marketing | numeric | 0 |
| Profit | numeric | 0 |
| Sales | numeric | 0 |
| Total.Expenses | numeric | 0 |
| Tahun | numeric | 0 |
| Bulan | numeric | 0 |
| YearMo | Date | 0 |
Interpretasi: Berdasarkan tabel di atas, tidak ditemukan missing value pada data sehingga dapat dilakukan analisis lebih lanjut tanpa melakukan imputasi terlebih dahulu.
Eksplorasi data dilakukan untuk memahami distribusi, variasi, dan hubungan antar variabel secara visual sebelum pengujian statistik.
p1 <- ggplot(df, aes(x = Sales)) +
geom_histogram(bins = 40, fill = "#2E86AB", color = "white", alpha = 0.85) +
labs(title = "Distribusi Sales", x = "Sales", y = "Frekuensi") +
theme_minimal()
p2 <- ggplot(df, aes(x = Profit)) +
geom_histogram(bins = 40, fill = "#A23B72", color = "white", alpha = 0.85) +
labs(title = "Distribusi Profit", x = "Profit", y = "Frekuensi") +
theme_minimal()
gridExtra::grid.arrange(p1, p2, ncol = 2)
Interpretasi: Berdasarkan histogram di atas, distribusi Sales dan Profit terlihat condong ke kanan (right-skewed), mengindikasikan bahwa sebagian besar transaksi memiliki nilai rendah hingga menengah dengan beberapa transaksi bernilai tinggi. Hal ini menjadi dasar penggunaan metode statistik non-parametrik pada tahapan selanjutnya.
p3 <- ggplot(df, aes(x = Product.Type, y = Sales, fill = Product.Type)) +
geom_boxplot(alpha = 0.8, outlier.shape = 16, outlier.size = 1) +
labs(title = "Distribusi Sales per Tipe Produk",
x = "Tipe Produk", y = "Sales") +
theme_minimal() + theme(legend.position = "none")
p4 <- ggplot(df, aes(x = Product.Type, y = Profit, fill = Product.Type)) +
geom_boxplot(alpha = 0.8, outlier.shape = 16, outlier.size = 1) +
labs(title = "Distribusi Profit per Tipe Produk",
x = "Tipe Produk", y = "Profit") +
theme_minimal() + theme(legend.position = "none")
gridExtra::grid.arrange(p3, p4, ncol = 2)
Interpretasi: Boxplot menunjukkan adanya variasi median Sales dan Profit antar tipe produk. Espresso dan Coffee tampak memiliki kisaran nilai yang lebih tinggi dibandingkan Herbal Tea dan Tea, meski terdapat banyak pencilan (outlier) pada semua kategori. Perbedaan ini akan diuji menggunakan Kruskal-Wallis pada sub-bab berikutnya.
df %>%
group_by(State) %>%
summarise(Total_Sales = sum(Sales), .groups = "drop") %>%
arrange(desc(Total_Sales)) %>%
ggplot(aes(x = reorder(State, Total_Sales), y = Total_Sales, fill = Total_Sales)) +
geom_col(alpha = 0.85) +
coord_flip() +
scale_fill_gradient(low = "#d4e9f7", high = "#1a5276") +
scale_y_continuous(labels = comma) +
labs(title = "Total Sales per State",
x = "State", y = "Total Sales", fill = "Total Sales") +
theme_minimal()
Interpretasi: California, Utah, dan Colorado tampak menjadi state dengan total penjualan tertinggi, sementara beberapa state seperti Massachusetts dan Louisiana berada di bawah.
df %>%
group_by(Market) %>%
summarise(Total_Sales = sum(Sales), Total_Profit = sum(Profit), .groups = "drop") %>%
pivot_longer(cols = c(Total_Sales, Total_Profit), names_to = "Metrik", values_to = "Nilai") %>%
ggplot(aes(x = Market, y = Nilai, fill = Metrik)) +
geom_col(position = "dodge", alpha = 0.85) +
scale_y_continuous(labels = comma) +
labs(title = "Perbandingan Sales dan Profit per Market",
x = "Market", y = "Nilai", fill = "Metrik") +
theme_minimal()
Interpretasi: Market West dan Central cenderung mendominasi dari sisi total Sales maupun Profit. Perbandingan antara Sales dan Profit menunjukkan pola margin yang relatif konsisten antar region.
df %>%
group_by(YearMo) %>%
summarise(Total_Sales = sum(Sales), .groups = "drop") %>%
ggplot(aes(x = YearMo, y = Total_Sales)) +
geom_line(color = "#2E86AB", linewidth = 1) +
geom_point(color = "#1a5276", size = 2) +
scale_y_continuous(labels = comma) +
scale_x_date(date_labels = "%b %Y", date_breaks = "2 months") +
labs(title = "Tren Sales Bulanan Coffee Chain (2012–2013)",
x = "Bulan", y = "Total Sales") +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
Interpretasi: Grafik tren bulanan memperlihatkan adanya fluktuasi penjualan sepanjang 2012–2013. Untuk mengidentifikasi pola dilakukan analisis pada sub-bab berikutnya.
ggplot(df, aes(x = Sales, y = Profit, color = Product.Type)) +
geom_point(alpha = 0.4, size = 1.2) +
labs(title = "Hubungan Sales dan Profit per Tipe Produk",
x = "Sales", y = "Profit", color = "Tipe Produk") +
theme_minimal()
Interpretasi: Terdapat hubungan positif yang kuat antara Sales dan Profit pada seluruh tipe produk.
Identifikasi pola deret waktu dilakukan untuk menentukan apakah data Sales memiliki komponen tren (kecenderungan naik/turun jangka panjang), musiman (pola berulang periodik), atau keduanya. Alat utama yang digunakan adalah fungsi autokorelasi (ACF).
Landasan Teori:
Fungsi Autokorelasi (ACF) pada lag \(k\) didefinisikan sebagai :
\[\hat{\rho}(k) = \frac{\sum_{t=k+1}^{T}(y_t - \bar{y})(y_{t-k} - \bar{y})}{\sum_{t=1}^{T}(y_t - \bar{y})^2}\]
di mana \(y_t\) adalah nilai deret waktu pada waktu \(t\), \(\bar{y}\) adalah rata-rata deret, dan \(T\) adalah panjang deret. Batas signifikansi (garis putus-putus pada plot ACF) adalah \(\pm 1.96/\sqrt{T}\).
monthly_sales <- df %>%
group_by(YearMo) %>%
summarise(Total_Sales = sum(Sales), .groups = "drop") %>%
arrange(YearMo)
ts_sales <- ts(monthly_sales$Total_Sales, start = c(2012, 1), frequency = 12)
par(mfrow = c(1, 2))
acf(ts_sales, lag.max = 23, main = "ACF — Total Sales Bulanan")
pacf(ts_sales, lag.max = 23, main = "PACF — Total Sales Bulanan")
par(mfrow = c(1, 1))
decomp_sales <- decompose(ts_sales, type = "additive")
autoplot(decomp_sales) +
labs(title = "Dekomposisi Aditif — Total Sales Bulanan") +
theme_minimal()
Interpretasi:
Berdasarkan plot ACF, PACF, dan dekomposisi di atas:
Uji Kolmogorov-Smirnov (KS) adalah uji non-parametrik yang membandingkan fungsi distribusi kumulatif empiris \(F_n(x)\) dengan fungsi distribusi kumulatif teoritis \(F_0(x)\) (distribusi normal dalam konteks ini).
Statistik Uji:
\[D_n = \sup_x |F_n(x) - F_0(x)|\]
Nilai Kritis (pendekatan untuk \(n\) besar):
\[D_{\alpha} \approx \frac{c_\alpha}{\sqrt{n}}, \quad c_{0.05} = 1.36\]
Sehingga untuk \(n = 4248\):
\[D_{0.05} \approx \frac{1.36}{\sqrt{4248}} \approx 0.0209\]
Uji KS dilakukan terhadap setiap variabel numerik yang relevan. Parameter distribusi normal (rata-rata \(\mu\) dan simpangan baku \(\sigma\)) diestimasi dari data (lilliefors correction).
Hipotesis:
Tingkat Signifikansi: \(\alpha = 0.05\)
Daerah Kritis: Tolak \(H_0\) jika \(D_n > 0.0209\) atau \(p\text{-value} < 0.05\)
Statistik Uji:
ks.test(df$Sales, "pnorm", mean(df$Sales), sd(df$Sales))
##
## Asymptotic one-sample Kolmogorov-Smirnov test
##
## data: df$Sales
## D = 0.17561, p-value < 2.2e-16
## alternative hypothesis: two-sided
Kesimpulan: Berdasarkan output di atas, karena \(p\text{-value} < 0.05\), maka \(H_0\) ditolak — artinya data Sales tidak berdistribusi normal secara signifikan. Hal ini konsisten dengan bentuk histogram Sales yang condong ke kanan. Distribusi ini menjadi dasar penggunaan metode non-parametrik pada analisis selanjutnya.
Hipotesis:
Tingkat Signifikansi: \(\alpha = 0.05\)
Daerah Kritis: Tolak \(H_0\) jika \(D_n > 0.0209\) atau \(p\text{-value} < 0.05\)
Statistik Uji:
ks.test(df$Profit, "pnorm", mean(df$Profit), sd(df$Profit))
##
## Asymptotic one-sample Kolmogorov-Smirnov test
##
## data: df$Profit
## D = 0.18579, p-value < 2.2e-16
## alternative hypothesis: two-sided
Kesimpulan: Berdasarkan output di atas, karena \(p\text{-value} < 0.05\), maka \(H_0\) ditolak — artinya data Profit tidak berdistribusi normal secara signifikan. Hal ini konsisten dengan bentuk histogram Profit yang condong ke kanan. Distribusi ini menjadi dasar penggunaan metode non-parametrik pada analisis selanjutnya.
Hipotesis:
Tingkat Signifikansi: \(\alpha = 0.05\)
Daerah Kritis: Tolak \(H_0\) jika \(D_n > 0.0209\) atau \(p\text{-value} < 0.05\)
Statistik Uji:
ks.test(df$COGS, "pnorm", mean(df$COGS), sd(df$COGS))
##
## Asymptotic one-sample Kolmogorov-Smirnov test
##
## data: df$COGS
## D = 0.17486, p-value < 2.2e-16
## alternative hypothesis: two-sided
Kesimpulan: Berdasarkan output di atas, karena \(p\text{-value} < 0.05\), maka \(H_0\) ditolak — artinya data COGS tidak berdistribusi normal secara signifikan. Distribusi ini menjadi dasar penggunaan metode non-parametrik pada analisis selanjutnya.
Hipotesis:
Tingkat Signifikansi: \(\alpha = 0.05\)
Daerah Kritis: Tolak \(H_0\) jika \(D_n > 0.0209\) atau \(p\text{-value} < 0.05\)
Statistik Uji:
ks.test(df$Margin, "pnorm", mean(df$Margin), sd(df$Margin))
##
## Asymptotic one-sample Kolmogorov-Smirnov test
##
## data: df$Margin
## D = 0.1603, p-value < 2.2e-16
## alternative hypothesis: two-sided
Kesimpulan: Berdasarkan output di atas, karena \(p\text{-value} < 0.05\), maka \(H_0\) ditolak — artinya data Margin tidak berdistribusi normal secara signifikan. Distribusi ini menjadi dasar penggunaan metode non-parametrik pada analisis selanjutnya.
Hipotesis:
Tingkat Signifikansi: \(\alpha = 0.05\)
Daerah Kritis: Tolak \(H_0\) jika \(D_n > 0.0209\) atau \(p\text{-value} < 0.05\)
Statistik Uji:
ks.test(df$Marketing, "pnorm", mean(df$Marketing), sd(df$Marketing))
##
## Asymptotic one-sample Kolmogorov-Smirnov test
##
## data: df$Marketing
## D = 0.18759, p-value < 2.2e-16
## alternative hypothesis: two-sided
Kesimpulan: Berdasarkan output di atas, karena \(p\text{-value} < 0.05\), maka \(H_0\) ditolak — artinya data Marketing tidak berdistribusi normal secara signifikan. Distribusi ini menjadi dasar penggunaan metode non-parametrik pada analisis selanjutnya.
Hipotesis:
Tingkat Signifikansi: \(\alpha = 0.05\)
Daerah Kritis: Tolak \(H_0\) jika \(D_n > 0.0209\) atau \(p\text{-value} < 0.05\)
Statistik Uji:
ks.test(df$Inventory, "pnorm", mean(df$Inventory), sd(df$Inventory))
##
## Asymptotic one-sample Kolmogorov-Smirnov test
##
## data: df$Inventory
## D = 0.17249, p-value < 2.2e-16
## alternative hypothesis: two-sided
Kesimpulan: Berdasarkan output di atas, karena \(p\text{-value} < 0.05\), maka \(H_0\) ditolak — artinya data Inventory tidak berdistribusi normal secara signifikan. Distribusi ini menjadi dasar penggunaan metode non-parametrik pada analisis selanjutnya.
Hipotesis:
Tingkat Signifikansi: \(\alpha = 0.05\)
Daerah Kritis: Tolak \(H_0\) jika \(D_n > 0.0209\) atau \(p\text{-value} < 0.05\)
Statistik Uji:
ks.test(df$Total.Expenses, "pnorm", mean(df$Total.Expenses), sd(df$Total.Expenses))
##
## Asymptotic one-sample Kolmogorov-Smirnov test
##
## data: df$Total.Expenses
## D = 0.13762, p-value < 2.2e-16
## alternative hypothesis: two-sided
Kesimpulan: Berdasarkan output di atas, karena \(p\text{-value} < 0.05\), maka \(H_0\) ditolak — artinya data Expenses tidak berdistribusi normal secara signifikan. Distribusi ini menjadi dasar penggunaan metode non-parametrik pada analisis selanjutnya.
var_list <- list(
Sales = df$Sales,
Profit = df$Profit,
COGS = df$COGS,
Margin = df$Margin,
Marketing = df$Marketing,
Inventory = df$Inventory,
Total.Expenses = df$Total.Expenses
)
rekap_ks <- lapply(names(var_list), function(nm) {
x <- var_list[[nm]]
res <- ks.test(x, "pnorm", mean(x), sd(x))
data.frame(
Variabel = nm,
D_statistic = round(res$statistic, 5),
p_value = formatC(res$p.value, format = "e", digits = 3),
Keputusan = ifelse(res$p.value < 0.05, "Tolak H0 (Tidak Normal)", "Gagal Tolak H0 (Normal)")
)
})
do.call(rbind, rekap_ks) %>%
kable(caption = "Rekapitulasi Uji Normalitas Kolmogorov-Smirnov (α = 0.05)",
row.names = FALSE) %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed"))
| Variabel | D_statistic | p_value | Keputusan |
|---|---|---|---|
| Sales | 0.17561 | 3.274e-114 | Tolak H0 (Tidak Normal) |
| Profit | 0.18579 | 8.752e-128 | Tolak H0 (Tidak Normal) |
| COGS | 0.17486 | 3.039e-113 | Tolak H0 (Tidak Normal) |
| Margin | 0.16030 | 3.080e-95 | Tolak H0 (Tidak Normal) |
| Marketing | 0.18759 | 2.876e-130 | Tolak H0 (Tidak Normal) |
| Inventory | 0.17249 | 3.266e-110 | Tolak H0 (Tidak Normal) |
| Total.Expenses | 0.13762 | 2.606e-70 | Tolak H0 (Tidak Normal) |
Interpretasi Umum: Berdasarkan tabel di atas, seluruh variabel numerik tidak memenuhi asumsi normalitas pada \(\alpha = 0.05\). Kondisi ini mengkonfirmasi bahwa metode statistik non-parametrik merupakan pilihan yang tepat untuk analisis komparatif dan korelasi pada dataset ini.
Uji Kruskal-Wallis adalah uji non-parametrik satu arah yang digunakan untuk menguji apakah \(k\) kelompok independen berasal dari distribusi yang sama. Uji ini merupakan alternatif dari ANOVA satu faktor ketika asumsi normalitas tidak terpenuhi.
Statistik Uji:
\[H = \frac{12}{N(N+1)} \sum_{i=1}^{k} \frac{R_i^2}{n_i} - 3(N+1)\]
di mana: - \(N\) = total observasi seluruh kelompok - \(k\) = jumlah kelompok - \(n_i\) = jumlah observasi pada kelompok ke-\(i\) - \(R_i\) = jumlah peringkat pada kelompok ke-\(i\)
Statistik \(H\) terdistribusi \(\chi^2\) dengan derajat bebas \(df = k - 1\).
Uji Lanjut Dunn Test:
Jika \(H_0\) ditolak, dilakukan uji pasca-hoc Dunn untuk mengidentifikasi pasangan kelompok mana yang berbeda signifikan. Statistik uji Dunn:
\[z_{ij} = \frac{\bar{R}_i - \bar{R}_j}{\sqrt{\frac{N(N+1)}{12}\left(\frac{1}{n_i} + \frac{1}{n_j}\right)}}\]
Koreksi Bonferroni diterapkan untuk mengendalikan tingkat kesalahan tipe I pada perbandingan multipel.
Hipotesis:
Tingkat Signifikansi: \(\alpha = 0.05\)
Daerah Kritis: Tolak \(H_0\) jika \(H > \chi^2_{0.05;\, df=3} = 7.815\) atau \(p\text{-value} < 0.05\)
Statistik Uji Kruskal-Wallis:
kruskal.test(Profit ~ Product.Type, data = df)
##
## Kruskal-Wallis rank sum test
##
## data: Profit by Product.Type
## Kruskal-Wallis chi-squared = 2.4137, df = 3, p-value = 0.4911
Kesimpulan Kruskal-Wallis: Karena \(H < 7.815\) dan \(p\text{-value} > 0.05\), maka \(H_0\) gagall ditolak yang berarti tidak terdapat perbedaan signifikan Profit antar tipe produk.
Hipotesis:
Tingkat Signifikansi: \(\alpha = 0.05\)
Daerah Kritis: Tolak \(H_0\) jika \(H > \chi^2_{0.05;\, df=3} = 7.815\) atau \(p\text{-value} < 0.05\)
Statistik Uji Kruskal-Wallis:
kruskal.test(Sales ~ Product.Type, data = df)
##
## Kruskal-Wallis rank sum test
##
## data: Sales by Product.Type
## Kruskal-Wallis chi-squared = 41.245, df = 3, p-value = 5.802e-09
Kesimpulan Kruskal-Wallis: Karena \(H > 7.815\) dan \(p\text{-value} < 0.05\), maka \(H_0\) ditolak yang berarti terdapat perbedaan signifikan Sales antar tipe produk. Uji lanjut Dunn dilakukan untuk mengidentifikasi pasangan yang berbeda.
Uji Lanjut: Post-hoc Dunn Test (Koreksi Bonferroni)
Hipotesis (per pasangan):
Tingkat Signifikansi: \(\alpha = 0.05\) (setelah koreksi Bonferroni)
Daerah Kritis: Tolak \(H_0^{(ij)}\) jika \(p\text{-adj} < 0.05\)
Statistik Uji Dunn:
dunn_sales_produk <- dunnTest(Sales ~ Product.Type, data = df, method = "bonferroni")
dunn_sales_produk$res %>%
kable(caption = "Post-hoc Dunn Test: Sales per Tipe Produk (Bonferroni)",
digits = 4) %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed"))
| Comparison | Z | P.unadj | P.adj |
|---|---|---|---|
| Coffee - Espresso | 3.7703 | 0.0002 | 0.0010 |
| Coffee - Herbal Tea | 0.1533 | 0.8782 | 1.0000 |
| Espresso - Herbal Tea | -3.6129 | 0.0003 | 0.0018 |
| Coffee - Tea | 5.2512 | 0.0000 | 0.0000 |
| Espresso - Tea | 1.7089 | 0.0875 | 0.5248 |
| Herbal Tea - Tea | 5.1016 | 0.0000 | 0.0000 |
Kesimpulan Post-hoc: Hasil uji post-hoc Dunn (Bonferroni) menunjukkan bahwa pasangan produk yang berbeda signifikan dalam penjualan adalah: Coffee–Espresso, Espresso–Herbal Tea, Coffee–Tea, dan Herbal Tea–Tea (p.adj < 0,05). Sementara itu, pasangan yang tidak berbeda signifikan adalah Coffee–Herbal Tea dan Espresso–Tea (p.adj > 0,05).
Meskipun terdapat perbedaan pada sales antar beberapa pasangan produk, profit antar tipe produk tidak menunjukkan perbedaan yang signifikan secara statistik.
Pada pengujian ini, jumlah kelompok \(k = 20\) (20 state), sehingga \(df = 19\) dan nilai kritis \(\chi^2_{0.05;\, 19} = 30.144\). Uji lanjut menggunakan koreksi Bonferroni dengan total \(\binom{20}{2} = 190\) pasangan perbandingan.
Hipotesis:
Tingkat Signifikansi: \(\alpha = 0.05\)
Daerah Kritis: Tolak \(H_0\) jika \(H > \chi^2_{0.05;\, df=19} = 30.144\) atau \(p\text{-value} < 0.05\)
Statistik Uji Kruskal-Wallis:
kruskal.test(Profit ~ State, data = df)
##
## Kruskal-Wallis rank sum test
##
## data: Profit by State
## Kruskal-Wallis chi-squared = 950.82, df = 19, p-value < 2.2e-16
Kesimpulan Kruskal-Wallis: Karena \(H > 30.144\) dan \(p\text{-value} < 0.05\), maka \(H_0\) ditolak yang berarti terdapat perbedaan signifikan Profit antar state.
Uji Lanjut: Post-hoc Dunn Test (Koreksi Bonferroni)
Hipotesis (per pasangan):
Tingkat Signifikansi: \(\alpha = 0.05\) (setelah koreksi Bonferroni)
Daerah Kritis: Tolak \(H_0^{(ij)}\) jika \(p\text{-adj} < 0.05\)
Statistik Uji Dunn:
dunn_profit_state <- dunnTest(Profit ~ State, data = df, method = "bonferroni")
# Tampilkan hanya pasangan yang signifikan
dunn_state_sig <- dunn_profit_state$res[dunn_profit_state$res$P.adj < 0.05, ]
dunn_state_sig %>%
arrange(P.adj) %>%
kable(caption = "Post-hoc Dunn Test: Profit per State — Pasangan Signifikan (p.adj < 0.05, Bonferroni)",
digits = 4) %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed"))
| Comparison | Z | P.unadj | P.adj |
|---|---|---|---|
| Illinois - New Mexico | 20.8409 | 0e+00 | 0.0000 |
| Illinois - Missouri | 18.4018 | 0e+00 | 0.0000 |
| Illinois - New Hampshire | 17.8882 | 0e+00 | 0.0000 |
| California - New Mexico | 16.8307 | 0e+00 | 0.0000 |
| Illinois - Utah | 16.6247 | 0e+00 | 0.0000 |
| New Mexico - New York | -15.5937 | 0e+00 | 0.0000 |
| New Mexico - Texas | -14.9409 | 0e+00 | 0.0000 |
| California - Missouri | 14.0068 | 0e+00 | 0.0000 |
| California - New Hampshire | 13.7019 | 0e+00 | 0.0000 |
| Illinois - Oregon | 13.3005 | 0e+00 | 0.0000 |
| Colorado - New Mexico | 13.1426 | 0e+00 | 0.0000 |
| Missouri - New York | -12.8467 | 0e+00 | 0.0000 |
| New Hampshire - New York | -12.7186 | 0e+00 | 0.0000 |
| Illinois - Wisconsin | 12.5582 | 0e+00 | 0.0000 |
| Illinois - Nevada | 12.3153 | 0e+00 | 0.0000 |
| Illinois - Ohio | 12.2975 | 0e+00 | 0.0000 |
| Missouri - Texas | -12.2196 | 0e+00 | 0.0000 |
| Iowa - New Mexico | 12.1807 | 0e+00 | 0.0000 |
| Florida - New Mexico | 12.1782 | 0e+00 | 0.0000 |
| New Hampshire - Texas | -12.1570 | 0e+00 | 0.0000 |
| Illinois - Washington | 11.8376 | 0e+00 | 0.0000 |
| California - Utah | 11.8373 | 0e+00 | 0.0000 |
| Connecticut - Illinois | -11.5022 | 0e+00 | 0.0000 |
| Illinois - Massachusetts | 11.1603 | 0e+00 | 0.0000 |
| Illinois - Oklahoma | 10.9259 | 0e+00 | 0.0000 |
| New York - Utah | 10.7321 | 0e+00 | 0.0000 |
| Illinois - Louisiana | 10.5445 | 0e+00 | 0.0000 |
| New Mexico - Washington | -10.2755 | 0e+00 | 0.0000 |
| Nevada - New Mexico | 10.2742 | 0e+00 | 0.0000 |
| Texas - Utah | 10.1225 | 0e+00 | 0.0000 |
| Colorado - Missouri | 10.0702 | 0e+00 | 0.0000 |
| Colorado - New Hampshire | 10.0649 | 0e+00 | 0.0000 |
| Louisiana - New Mexico | 9.7076 | 0e+00 | 0.0000 |
| New Mexico - Oregon | -9.3583 | 0e+00 | 0.0000 |
| New Mexico - Oklahoma | -9.3480 | 0e+00 | 0.0000 |
| New Mexico - Ohio | -9.3377 | 0e+00 | 0.0000 |
| Florida - Illinois | -9.2608 | 0e+00 | 0.0000 |
| Illinois - Iowa | 9.2581 | 0e+00 | 0.0000 |
| Colorado - Illinois | -9.2297 | 0e+00 | 0.0000 |
| Iowa - New Hampshire | 9.2280 | 0e+00 | 0.0000 |
| Florida - New Hampshire | 9.2254 | 0e+00 | 0.0000 |
| Iowa - Missouri | 9.1436 | 0e+00 | 0.0000 |
| Florida - Missouri | 9.1409 | 0e+00 | 0.0000 |
| New Mexico - Wisconsin | -9.0938 | 0e+00 | 0.0000 |
| Connecticut - New Mexico | 8.8046 | 0e+00 | 0.0000 |
| California - Oregon | 8.3366 | 0e+00 | 0.0000 |
| Massachusetts - New Mexico | 8.3057 | 0e+00 | 0.0000 |
| California - Wisconsin | 7.7598 | 0e+00 | 0.0000 |
| New York - Oregon | 7.6311 | 0e+00 | 0.0000 |
| Colorado - Utah | 7.6238 | 0e+00 | 0.0000 |
| California - Ohio | 7.4811 | 0e+00 | 0.0000 |
| California - Nevada | 7.2757 | 0e+00 | 0.0000 |
| New Hampshire - Washington | -7.2560 | 0e+00 | 0.0000 |
| Nevada - New Hampshire | 7.1965 | 0e+00 | 0.0000 |
| New York - Wisconsin | 7.1776 | 0e+00 | 0.0000 |
| Oregon - Texas | -7.1595 | 0e+00 | 0.0000 |
| Missouri - Washington | -7.0422 | 0e+00 | 0.0000 |
| Missouri - Nevada | -6.9846 | 0e+00 | 0.0000 |
| California - Connecticut | 6.9352 | 0e+00 | 0.0000 |
| New York - Ohio | 6.9247 | 0e+00 | 0.0000 |
| Louisiana - New Hampshire | 6.9237 | 0e+00 | 0.0000 |
| California - Washington | 6.8681 | 0e+00 | 0.0000 |
| California - Massachusetts | 6.7675 | 0e+00 | 0.0000 |
| Texas - Wisconsin | 6.7534 | 0e+00 | 0.0000 |
| Iowa - Utah | 6.7273 | 0e+00 | 0.0000 |
| Florida - Utah | 6.7244 | 0e+00 | 0.0000 |
| Nevada - New York | -6.6780 | 0e+00 | 0.0000 |
| New Mexico - Utah | -6.6696 | 0e+00 | 0.0000 |
| Louisiana - Missouri | 6.6688 | 0e+00 | 0.0000 |
| New Hampshire - Oklahoma | -6.5641 | 0e+00 | 0.0000 |
| Ohio - Texas | -6.5096 | 0e+00 | 0.0000 |
| Connecticut - New York | -6.5004 | 0e+00 | 0.0000 |
| Massachusetts - New York | -6.3876 | 0e+00 | 0.0000 |
| New Hampshire - Ohio | -6.3849 | 0e+00 | 0.0000 |
| New York - Washington | 6.3387 | 0e+00 | 0.0000 |
| California - Oklahoma | 6.3245 | 0e+00 | 0.0000 |
| Missouri - Oklahoma | -6.2874 | 0e+00 | 0.0000 |
| New Hampshire - Oregon | -6.2806 | 0e+00 | 0.0000 |
| Nevada - Texas | -6.2436 | 0e+00 | 0.0000 |
| New Hampshire - Wisconsin | -6.1411 | 0e+00 | 0.0000 |
| Connecticut - Texas | -6.1363 | 0e+00 | 0.0000 |
| Missouri - Ohio | -6.1043 | 0e+00 | 0.0000 |
| Massachusetts - Texas | -6.0491 | 0e+00 | 0.0000 |
| Connecticut - New Hampshire | 6.0207 | 0e+00 | 0.0000 |
| Missouri - Oregon | -5.9994 | 0e+00 | 0.0000 |
| New York - Oklahoma | 5.9392 | 0e+00 | 0.0000 |
| Texas - Washington | 5.9302 | 0e+00 | 0.0000 |
| California - Louisiana | 5.9203 | 0e+00 | 0.0000 |
| Missouri - Wisconsin | -5.8436 | 0e+00 | 0.0000 |
| Connecticut - Missouri | 5.7110 | 0e+00 | 0.0000 |
| California - Illinois | -5.6655 | 0e+00 | 0.0000 |
| Massachusetts - New Hampshire | 5.6310 | 0e+00 | 0.0000 |
| Oklahoma - Texas | -5.5929 | 0e+00 | 0.0000 |
| Louisiana - New York | -5.5678 | 0e+00 | 0.0000 |
| Massachusetts - Missouri | 5.2988 | 0e+00 | 0.0000 |
| Louisiana - Texas | -5.2333 | 0e+00 | 0.0000 |
| Illinois - New York | 5.0056 | 0e+00 | 0.0001 |
| Illinois - Texas | 4.9937 | 0e+00 | 0.0001 |
| Utah - Washington | -4.4183 | 0e+00 | 0.0019 |
| Nevada - Utah | 4.3013 | 0e+00 | 0.0032 |
| Colorado - Oregon | 4.2910 | 0e+00 | 0.0034 |
| Louisiana - Utah | 4.2407 | 0e+00 | 0.0042 |
| California - Florida | 4.2348 | 0e+00 | 0.0043 |
| California - Iowa | 4.2319 | 0e+00 | 0.0044 |
| Florida - New York | -3.9787 | 1e-04 | 0.0132 |
| Iowa - New York | -3.9761 | 1e-04 | 0.0133 |
| California - Colorado | 3.9533 | 1e-04 | 0.0146 |
| Colorado - Wisconsin | 3.9414 | 1e-04 | 0.0154 |
| Oklahoma - Utah | 3.8366 | 1e-04 | 0.0237 |
| Colorado - New York | -3.6933 | 2e-04 | 0.0421 |
| Florida - Texas | -3.6690 | 2e-04 | 0.0463 |
| Colorado - Ohio | 3.6680 | 2e-04 | 0.0464 |
| Iowa - Texas | -3.6665 | 2e-04 | 0.0467 |
Kesimpulan Post-hoc: Tabel di atas menampilkan hanya pasangan state yang memiliki perbedaan Profit signifikan (\(p\text{-adj} < 0.05\)). Pasangan dengan nilai \(Z\) positif menunjukkan state pertama memiliki peringkat Profit lebih tinggi dari state kedua, dan sebaliknya.
K-Means adalah algoritma klasterisasi yang mempartisi \(n\) observasi ke dalam \(k\) klaster dengan meminimalkan jumlah kuadrat jarak (Within-Cluster Sum of Squares, WCSS) dari setiap observasi terhadap centroid klasternya:
\[\underset{S}{\arg\min} \sum_{i=1}^{k} \sum_{\mathbf{x} \in S_i} \|\mathbf{x} - \boldsymbol{\mu}_i\|^2\]
di mana \(S_i\) adalah himpunan observasi dalam klaster ke-\(i\) dan \(\boldsymbol{\mu}_i\) adalah rata-rata (centroid) klaster ke-\(i\).
Penentuan jumlah klaster optimal dilakukan menggunakan Metode Elbow, yaitu memilih \(k\) pada titik “siku” di mana penurunan WCSS mulai melandai secara signifikan [@kaufman1990]. Kualitas klaster dievaluasi menggunakan Silhouette Score, dengan nilai mendekati 1 mengindikasikan klaster yang terpisah dengan baik.
state_summary <- df %>%
group_by(State) %>%
summarise(
Total_Sales = sum(Sales),
Total_Profit = sum(Profit),
Mean_Margin = mean(Margin),
Mean_Marketing = mean(Marketing),
Mean_COGS = mean(COGS),
n_transaksi = n(),
.groups = "drop"
)
# Normalisasi fitur (Z-score)
state_scaled <- scale(state_summary[, -1])
rownames(state_scaled) <- state_summary$State
set.seed(42)
wss_values <- sapply(1:10, function(k) {
kmeans(state_scaled, centers = k, nstart = 25)$tot.withinss
})
data.frame(k = 1:10, WSS = wss_values) %>%
ggplot(aes(x = k, y = WSS)) +
geom_line(color = "#2E86AB", linewidth = 1) +
geom_point(size = 3, color = "#1a5276") +
scale_x_continuous(breaks = 1:10) +
labs(title = "Metode Elbow — Penentuan Jumlah Klaster Optimal",
x = "Jumlah Klaster (k)", y = "Within-Cluster Sum of Squares (WSS)") +
theme_minimal()
Interpretasi Elbow: Berdasarkan grafik WSS terhadap \(k\), titik “siku” yang paling jelas terletak pada \(k = 3\). Pemilihan \(k\) dilakukan pada titik di mana penurunan WSS mulai melandai secara signifikan.
set.seed(42)
k_optimal <- 3 # Sesuaikan berdasarkan grafik elbow
km_result <- kmeans(state_scaled, centers = k_optimal, nstart = 25)
state_summary$Klaster <- factor(km_result$cluster)
state_summary %>%
group_by(Klaster) %>%
summarise(
Jumlah_State = n(),
Rata_Sales = round(mean(Total_Sales), 0),
Rata_Profit = round(mean(Total_Profit), 0),
Rata_Margin = round(mean(Mean_Margin), 2),
Rata_Marketing = round(mean(Mean_Marketing), 2),
.groups = "drop"
) %>%
kable(caption = "Profil Rata-rata Klaster (K-Means, k = 3)") %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed"))
| Klaster | Jumlah_State | Rata_Sales | Rata_Profit | Rata_Margin | Rata_Marketing |
|---|---|---|---|---|---|
| 1 | 3 | 79209 | 27567 | 176.72 | 55.07 |
| 2 | 7 | 23063 | 6732 | 79.60 | 22.00 |
| 3 | 10 | 42074 | 12972 | 98.41 | 29.09 |
state_summary %>%
select(State, Klaster, Total_Sales, Total_Profit, Mean_Margin) %>%
arrange(Klaster, desc(Total_Sales)) %>%
kable(caption = "Anggota Klaster per State",
col.names = c("State", "Klaster", "Total Sales", "Total Profit", "Rata-rata Margin"),
digits = 2) %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed")) %>%
row_spec(which(state_summary %>% arrange(Klaster, desc(Total_Sales)) %>% pull(Klaster) == 1),
background = "#d6eaf8") %>%
row_spec(which(state_summary %>% arrange(Klaster, desc(Total_Sales)) %>% pull(Klaster) == 2),
background = "#d5f5e3") %>%
row_spec(which(state_summary %>% arrange(Klaster, desc(Total_Sales)) %>% pull(Klaster) == 3),
background = "#fdebd0")
| State | Klaster | Total Sales | Total Profit | Rata-rata Margin |
|---|---|---|---|---|
| California | 1 | 96892 | 31785 | 171.53 |
| New York | 1 | 70852 | 20096 | 178.29 |
| Illinois | 1 | 69883 | 30821 | 180.34 |
| Massachusetts | 2 | 29965 | 16442 | 140.61 |
| Oklahoma | 2 | 27463 | 8558 | 93.14 |
| Connecticut | 2 | 25429 | 7621 | 85.43 |
| Missouri | 2 | 24647 | 3601 | 58.66 |
| Louisiana | 2 | 23161 | 7355 | 78.77 |
| New Mexico | 2 | 15892 | 799 | 47.49 |
| New Hampshire | 2 | 14887 | 2748 | 53.12 |
| Nevada | 3 | 60159 | 10616 | 101.73 |
| Iowa | 3 | 54750 | 22212 | 139.25 |
| Colorado | 3 | 48179 | 17743 | 101.20 |
| Oregon | 3 | 40899 | 12439 | 85.95 |
| Washington | 3 | 38930 | 11405 | 92.74 |
| Florida | 3 | 37443 | 12310 | 98.08 |
| Texas | 3 | 37410 | 15766 | 124.60 |
| Utah | 3 | 35384 | 7751 | 65.43 |
| Ohio | 3 | 34517 | 10773 | 88.51 |
| Wisconsin | 3 | 33069 | 8702 | 86.65 |
Klaster ditampilkan pada peta geografis Amerika Serikat menggunakan choropleth map interaktif, sehingga distribusi spasial kinerja setiap state dapat terlihat secara langsung. State yang tidak termasuk dalam dataset Coffee Chain ditampilkan dengan warna abu-abu.
# Pemetaan nama state ke kode 2 huruf (built-in R vector)
state_abbrev_lookup <- setNames(state.abb, state.name)
state_map_data <- state_summary %>%
mutate(Abbrev = state_abbrev_lookup[as.character(State)])
# Colorscale bertangga (step function) untuk warna diskrit per klaster
cs_step <- list(
list(0, "#2196F3"), # Klaster 1 — Biru
list(1/3, "#2196F3"),
list(1/3, "#FF9800"), # Klaster 2 — Oranye
list(2/3, "#FF9800"),
list(2/3, "#4CAF50"), # Klaster 3 — Hijau
list(1, "#4CAF50")
)
state_map_data <- state_map_data %>%
mutate(hover_text = paste0(
"<b>", State, "</b><br>",
"<b>Klaster ", Klaster, "</b><br>",
"─────────────────────<br>",
"Total Sales : $", comma(Total_Sales), "<br>",
"Total Profit : $", comma(Total_Profit), "<br>",
"Rata-rata Margin : ", round(Mean_Margin, 1), "<br>",
"Rata-rata Marketing: ", round(Mean_Marketing, 1)
))
plot_ly(
state_map_data,
type = "choropleth",
locations = ~Abbrev,
locationmode = "USA-states",
z = ~as.integer(Klaster),
text = ~hover_text,
hoverinfo = "text",
colorscale = cs_step,
zmin = 1,
zmax = 3,
colorbar = list(
title = "<b>Klaster</b>",
tickvals = c(1.33, 2, 2.67),
ticktext = c("Klaster 1", "Klaster 2", "Klaster 3"),
len = 0.4,
thickness = 20
),
marker = list(line = list(color = "white", width = 1.5))
) %>%
layout(
title = list(
text = paste0(
"<b>Peta Klasterisasi State Coffee Chain</b>",
"<br><sup>K-Means (k = 3) | Fitur: Total Sales, Total Profit, Avg Margin, Avg Marketing</sup>"
),
x = 0.5
),
geo = list(
scope = "usa",
projection = list(type = "albers usa"),
showlakes = TRUE,
lakecolor = toRGB("#cce5ff"),
showland = TRUE,
landcolor = toRGB("#f5f5f5"),
showcoastlines = TRUE,
coastlinecolor = toRGB("gray60"),
showframe = FALSE,
bgcolor = toRGB("white")
),
margin = list(l = 10, r = 10, t = 80, b = 10),
paper_bgcolor = "white"
)
state_map_usmap <- state_map_data %>%
rename(state = State) %>% # usmap mengharapkan kolom bernama 'state'
mutate(Klaster_Label = paste("Klaster", Klaster))
plot_usmap(
data = state_map_usmap,
values = "Klaster_Label",
color = "white",
linewidth = 0.5
) +
scale_fill_manual(
values = c(
"Klaster 1" = "#2196F3",
"Klaster 2" = "#FF9800",
"Klaster 3" = "#4CAF50",
"NA" = "#e0e0e0"
),
na.value = "#e0e0e0",
name = "Klaster"
) +
labs(
title = "Sebaran Geografis Klaster State Coffee Chain",
subtitle = "K-Means (k = 3) | State abu-abu tidak termasuk dalam dataset"
) +
theme(
legend.position = "right",
plot.title = element_text(face = "bold", size = 13),
plot.subtitle = element_text(size = 9, color = "gray40"),
legend.title = element_text(face = "bold")
)
sil <- silhouette(km_result$cluster, dist(state_scaled))
fviz_silhouette(sil) +
labs(title = "Silhouette Plot — Kualitas Klaster K-Means") +
theme_minimal()
## cluster size ave.sil.width
## 1 1 3 0.40
## 2 2 7 0.38
## 3 3 10 0.25
Interpretasi Klasterisasi:
Berdasarkan hasil K-Means dengan \(k = 3\) klaster [@macqueen1967; @hartigan1979]:
Nilai Silhouette Score rata-rata yang mendekati 1 mengindikasikan bahwa klaster terbentuk dengan baik dan terpisah secara jelas.
Korelasi Spearman (\(r_s\)) adalah ukuran korelasi non-parametrik yang mengukur kekuatan dan arah hubungan monoton antara dua variabel berdasarkan peringkat (rank) [@spearman1904; @conover1999].
Rumus koefisien Spearman:
\[r_s = 1 - \frac{6\sum_{i=1}^{n} d_i^2}{n(n^2 - 1)}\]
di mana \(d_i = R(x_i) - R(y_i)\) adalah selisih peringkat observasi ke-\(i\) dan \(n\) adalah ukuran sampel.
Statistik uji (untuk \(n\) besar):
\[t = r_s\sqrt{\frac{n-2}{1-r_s^2}} \sim t_{n-2}\]
Interpretasi \(r_s\):
| Nilai \(|r_s|\) | Interpretasi |
|---|---|
| 0.00 – 0.19 | Sangat lemah |
| 0.20 – 0.39 | Lemah |
| 0.40 – 0.59 | Sedang |
| 0.60 – 0.79 | Kuat |
| 0.80 – 1.00 | Sangat kuat |
Untuk seluruh pengujian ini, digunakan \(n = 4248\) observasi sehingga nilai kritis \(t_{0.025;\, 4246} \approx 1.9605\).
Hipotesis:
Tingkat Signifikansi: \(\alpha = 0.05\)
Daerah Kritis: Tolak \(H_0\) jika \(|t| > 1.9605\) atau \(p\text{-value} < 0.05\)
Statistik Uji:
cor.test(df$Sales, df$COGS, method = "spearman", exact = FALSE)
##
## Spearman's rank correlation rho
##
## data: df$Sales and df$COGS
## S = 1152875845, p-value < 2.2e-16
## alternative hypothesis: true rho is not equal to 0
## sample estimates:
## rho
## 0.9097639
Kesimpulan: Karena \(p\text{-value} < 0.05\), maka \(H_0\) ditolak yang berarti terdapat korelasi Spearman yang signifikan antara Sales dan COGS dengan kekuatan positif sangat kuat sebesar 0.9097639.
Hal ini menunjukkan bahwa semakin tinggi nilai Sales (penjualan), maka nilai COGS (Cost of Goods Sold atau biaya pokok penjualan) juga cenderung meningkat secara signifikan. Secara bisnis, kondisi ini wajar karena peningkatan penjualan biasanya diikuti dengan peningkatan jumlah barang yang diproduksi atau dijual, sehingga biaya pokok yang dikeluarkan juga ikut naik.
Hipotesis:
Tingkat Signifikansi: \(\alpha = 0.05\)
Daerah Kritis: Tolak \(H_0\) jika \(|t| > 1.9605\) atau \(p\text{-value} < 0.05\)
Statistik Uji:
cor.test(df$Sales, df$Margin, method = "spearman", exact = FALSE)
##
## Spearman's rank correlation rho
##
## data: df$Sales and df$Margin
## S = 566659401, p-value < 2.2e-16
## alternative hypothesis: true rho is not equal to 0
## sample estimates:
## rho
## 0.9556473
Kesimpulan: Karena \(p\text{-value} < 0.05\), maka \(H_0\) ditolak yang berarti terdapat korelasi Spearman yang signifikan antara Sales dan Margin dengan kekuatan positif sangat kuat sebesar 0.9556473.
Hal ini menunjukkan bahwa peningkatan penjualan tidak hanya menaikkan pendapatan, tetapi juga meningkatkan selisih keuntungan per transaksi, sehingga kinerja bisnis menjadi semakin optimal.
Hipotesis:
Tingkat Signifikansi: \(\alpha = 0.05\)
Daerah Kritis: Tolak \(H_0\) jika \(|t| > 1.9605\) atau \(p\text{-value} < 0.05\)
Statistik Uji:
cor.test(df$Sales, df$Marketing, method = "spearman", exact = FALSE)
##
## Spearman's rank correlation rho
##
## data: df$Sales and df$Marketing
## S = 2463882518, p-value < 2.2e-16
## alternative hypothesis: true rho is not equal to 0
## sample estimates:
## rho
## 0.8071508
Kesimpulan: Karena \(p\text{-value} < 0.05\), maka \(H_0\) ditolak yang berarti terdapat korelasi Spearman yang signifikan antara Sales dan Marketing dengan kekuatan positif sangat kuat sebesar 0,8071508.
Hal ini menunjukkan bahwa strategi pemasaran memiliki peran penting dalam mendorong peningkatan penjualan, meskipun hubungan ini tidak sekuat margin.
Hipotesis:
Tingkat Signifikansi: \(\alpha = 0.05\)
Daerah Kritis: Tolak \(H_0\) jika \(|t| > 1.9605\) atau \(p\text{-value} < 0.05\)
Statistik Uji:
cor.test(df$Sales, df$Inventory, method = "spearman", exact = FALSE)
##
## Spearman's rank correlation rho
##
## data: df$Sales and df$Inventory
## S = 8007938723, p-value < 2.2e-16
## alternative hypothesis: true rho is not equal to 0
## sample estimates:
## rho
## 0.3732151
Kesimpulan: Karena \(p\text{-value} < 0.05\), maka \(H_0\) ditolak yang berarti terdapat korelasi Spearman yang signifikan antara Sales dan Inventory dengan kekuatan positif lemah sebesar 0,3732151.
Hal ini menunjukkan jumlah stok memiliki sedikit kecenderungan untuk berbanding lurus dengan penjualan.
Hipotesis:
Tingkat Signifikansi: \(\alpha = 0.05\)
Daerah Kritis: Tolak \(H_0\) jika \(|t| > 1.9605\) atau \(p\text{-value} < 0.05\)
Statistik Uji:
cor.test(df$Sales, df$Total.Expenses, method = "spearman", exact = FALSE)
##
## Spearman's rank correlation rho
##
## data: df$Sales and df$Total.Expenses
## S = 4173734665, p-value < 2.2e-16
## alternative hypothesis: true rho is not equal to 0
## sample estimates:
## rho
## 0.67332
Kesimpulan: Karena \(p\text{-value} < 0.05\), maka \(H_0\) ditolak yang berarti terdapat korelasi Spearman yang signifikan antara Sales dan Total Expenses dengan kekuatan positif kuat sebesar 0,67332.
Hal ini menunjukkan bahwa untuk menghasilkan penjualan yang lebih besar, perusahaan perlu mengeluarkan biaya operasional yang lebih tinggi, seperti distribusi, pemasaran, dan biaya lainnya.
Hipotesis:
Tingkat Signifikansi: \(\alpha = 0.05\)
Daerah Kritis: Tolak \(H_0\) jika \(|t| > 1.9605\) atau \(p\text{-value} < 0.05\)
Statistik Uji:
cor.test(df$Sales, df$Profit, method = "spearman", exact = FALSE)
##
## Spearman's rank correlation rho
##
## data: df$Sales and df$Profit
## S = 2909365515, p-value < 2.2e-16
## alternative hypothesis: true rho is not equal to 0
## sample estimates:
## rho
## 0.7722827
Kesimpulan: Korelasi kuat antara Sales dan Profit mencerminkan keeratan hubungan volume penjualan dengan keuntungan yang dihasilkan.
Hipotesis:
Tingkat Signifikansi: \(\alpha = 0.05\)
Daerah Kritis: Tolak \(H_0\) jika \(|t| > 1.9605\) atau \(p\text{-value} < 0.05\)
Statistik Uji:
cor.test(df$Profit, df$COGS, method = "spearman", exact = FALSE)
##
## Spearman's rank correlation rho
##
## data: df$Profit and df$COGS
## S = 4992928669, p-value < 2.2e-16
## alternative hypothesis: true rho is not equal to 0
## sample estimates:
## rho
## 0.6092013
Kesimpulan: Karena \(p\text{-value} < 0.05\), maka \(H_0\) ditolak yang berarti terdapat korelasi Spearman yang signifikan antara Profit dan CGOS dengan kekuatan positif kuat sebesar 0,6092013.
Hal ini menunjukkan peningkatan biaya pokok (yang terjadi karena volume penjualan meningkat), menghasilkan keuntungan lebih besar.
Hipotesis:
Tingkat Signifikansi: \(\alpha = 0.05\)
Daerah Kritis: Tolak \(H_0\) jika \(|t| > 1.9605\) atau \(p\text{-value} < 0.05\)
Statistik Uji:
cor.test(df$Profit, df$Margin, method = "spearman", exact = FALSE)
##
## Spearman's rank correlation rho
##
## data: df$Profit and df$Margin
## S = 2163873569, p-value < 2.2e-16
## alternative hypothesis: true rho is not equal to 0
## sample estimates:
## rho
## 0.8306327
Kesimpulan: Karena \(p\text{-value} < 0.05\), maka \(H_0\) ditolak yang berarti terdapat korelasi Spearman yang signifikan antara Profit dan Margin dengan kekuatan positif sangat kuat sebesar 0,8306327.
Hal ini menunjukkan semakin besar Margin, maka Profit akan meningkat secara signifikan
Hipotesis:
Tingkat Signifikansi: \(\alpha = 0.05\)
Daerah Kritis: Tolak \(H_0\) jika \(|t| > 1.9605\) atau \(p\text{-value} < 0.05\)
Statistik Uji:
cor.test(df$Profit, df$Marketing, method = "spearman", exact = FALSE)
##
## Spearman's rank correlation rho
##
## data: df$Profit and df$Marketing
## S = 8228563128, p-value < 2.2e-16
## alternative hypothesis: true rho is not equal to 0
## sample estimates:
## rho
## 0.3559468
Kesimpulan: Karena \(p\text{-value} < 0.05\), maka \(H_0\) ditolak yang berarti terdapat korelasi Spearman yang signifikan antara Profit dan Marketing dengan kekuatan positif lemah sebesar 0,3559468.
Hal ini menunjukkan peningkatan Marketing hanya sedikit berkaitan dengan kenaikan Profit. Artinya, tidak semua pengeluaran pemasaran langsung menghasilkan keuntungan yang sebanding.
Hipotesis:
Tingkat Signifikansi: \(\alpha = 0.05\)
Daerah Kritis: Tolak \(H_0\) jika \(|t| > 1.9605\) atau \(p\text{-value} < 0.05\)
Statistik Uji:
cor.test(df$Profit, df$Inventory, method = "spearman", exact = FALSE)
##
## Spearman's rank correlation rho
##
## data: df$Profit and df$Inventory
## S = 7721515313, p-value < 2.2e-16
## alternative hypothesis: true rho is not equal to 0
## sample estimates:
## rho
## 0.3956336
Kesimpulan: Karena \(p\text{-value} < 0.05\), maka \(H_0\) ditolak yang berarti terdapat korelasi Spearman yang signifikan antara Profit dan Inventory dengan kekuatan positif lemah sebesar 0,3956336.
Berdasarkan seluruh tahapan analisis yang telah dilakukan terhadap dataset Coffee Chain (2012–2013), dapat ditarik beberapa kesimpulan utama:
Karakteristik Data : Data sales dan profit menunjukkan distribusi yang tidak normal dan cenderung condong ke kanan (right-skewed). Hal ini menunjukkan bahwa sebagian besar transaksi berada pada nilai rendah hingga menengah, dengan sebagian kecil transaksi bernilai tinggi.
Pola Deret Waktu: Hasil analisis deret waktu menunjukkan bahwa data sales memiliki kecenderungan tren meningkat dalam jangka panjang, namun tidak ditemukan pola musiman yang signifikan. Dengan demikian, perubahan penjualan lebih dipengaruhi oleh tren dibandingkan fluktuasi musiman.
Uji Normalitas (KS): Seluruh variabel numerik yang diuji sebagian besar tidak memenuhi asumsi distribusi normal pada \(\alpha = 0.05\).
Uji Kruskal-Wallis (Profit & Sales per Tipe Produk): Tidak terdapat perbedaan signifikan pada profit antar tipe produk. Terdapat perbedaan signifikan pada sales antar tipe produk, yang menunjukkan adanya variasi volume penjualan.
Uji Kruskal-Wallis (Profit per State): Terdapat perbedaan Profit yang signifikan antar state, mengindikasikan adanya variasi kinerja geografis yang perlu mendapat perhatian manajemen.
Klasterisasi K-Means: Berdasarkan metode K-Means, state dapat dikelompokkan menjadi tiga klaster, yaitu:
Optimalisasi Strategi Produk: Perusahaan disarankan untuk tidak hanya berfokus pada peningkatan volume penjualan, tetapi juga mempertimbangkan aspek profitabilitas dari setiap tipe produk.
Strategi Regional Berbasis Klaster: State pada klaster berkinerja rendah perlu dievaluasi — apakah perlu peningkatan distribusi, promosi lokal, atau pertimbangan strategi penetrasi pasar yang berbeda.
Efisiensi Biaya: Karena tidak semua pengeluaran berkontribusi secara signifikan terhadap profit, perusahaan perlu melakukan evaluasi terhadap komponen biaya untuk meningkatkan efisiensi operasional..
Optimalisasi Program Pemasaran: Strategi pemasaran perlu dirancang secara lebih efektif dan terarah agar tidak hanya meningkatkan penjualan, tetapi juga memberikan dampak nyata terhadap peningkatan keuntungan.