1 Pendahuluan

1.1 Latar Belakang

Dalam industri minuman berbasis kopi dan teh, peningkatan volume penjualan (sales) sering kali diperlakukan sebagai indikator utama keberhasilan bisnis. Namun, asumsi ini menyimpan risiko analitis yang serius: tingginya penjualan tidak selalu berbanding lurus dengan tingginya keuntungan. Suatu produk dapat mencetak volume penjualan besar namun sekaligus menggerus margin karena struktur biaya yang tidak efisien — fenomena yang kerap luput dari pengamatan apabila analisis hanya berhenti pada laporan penjualan agregat.

Dataset Coffee Chain menyimpan catatan transaksi dari sebuah jaringan kedai kopi yang beroperasi di empat wilayah pasar di Amerika Serikat: Central, East, South, dan West. Data ini mencakup informasi penjualan, biaya produksi (COGS), margin, pengeluaran pemasaran, serta profit aktual untuk 13 produk yang tersebar dalam empat kategori: Coffee, Espresso, Tea, dan Herbal Tea.

1.2 Tujuan Analisis

Laporan ini bertujuan untuk:

  1. Mengidentifikasi segmen produk dan wilayah pasar yang mengalami inefisiensi profitabilitas — yaitu kondisi di mana sales tinggi tidak diikuti oleh profit yang proporsional.
  2. Mengukur secara kuantitatif pengaruh relatif Sales dan Margin terhadap Profit menggunakan analisis regresi.
  3. Melakukan segmentasi berbasis kinerja untuk mengklasifikasikan produk ke dalam kuadran performa.
  4. Memberikan rekomendasi bisnis yang dapat ditindaklanjuti berdasarkan temuan empiris.

1.3 Hipotesis Analitis

Berdasarkan eksplorasi awal data, laporan ini menguji hipotesis bahwa: margin (selisih antara harga jual dan harga pokok) memiliki pengaruh yang lebih dominan terhadap profit dibandingkan volume sales itu sendiri, dan bahwa terdapat kelompok produk maupun wilayah yang secara struktural beroperasi dengan profit negatif meski mencatatkan sales yang cukup besar.


2 Deskripsi Data

2.1 Sumber dan Struktur Data

Dataset Coffee Chain diperoleh dari SPADA UNS dalam format .xlsx. Data mencakup 4.248 observasi dengan 20 variabel, merepresentasikan catatan penjualan periode 2012–2014 pada jaringan kedai kopi multiwilayah.

library(tidyverse)
library(readxl)
library(scales)
library(knitr)
library(cluster)
df_raw <- read_excel("Coffee Chain Datasets.xlsx")

# Rename kolom yang mengandung spasi agar compatible dengan sintaks R
df <- df_raw %>%
  rename(
    Area_Code      = `Area Code`,
    Market_Size    = `Market Size`,
    Product_Line   = `Product Line`,
    Product_Type   = `Product Type`,
    Budget_COGS    = `Budget COGS`,
    Budget_Margin  = `Budget Margin`,
    Budget_Profit  = `Budget Profit`,
    Budget_Sales   = `Budget Sales`,
    Total_Expenses = `Total Expenses`
  )

# Pratinjau dimensi dan struktur data
cat("Dimensi data:", nrow(df), "baris x", ncol(df), "kolom\n\n")
## Dimensi data: 4248 baris x 20 kolom
glimpse(df)
## 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-0…
## $ Market         <chr> "Central", "Central", "Central", "Central", "Central", …
## $ Market_Size    <chr> "Major Market", "Major Market", "Major Market", "Major …
## $ Product        <chr> "Amaretto", "Colombian", "Decaf Irish Cream", "Green Te…
## $ Product_Line   <chr> "Beans", "Beans", "Beans", "Leaves", "Beans", "Beans", …
## $ Product_Type   <chr> "Coffee", "Coffee", "Coffee", "Tea", "Espresso", "Espre…
## $ State          <chr> "Colorado", "Colorado", "Colorado", "Colorado", "Colora…
## $ Type           <chr> "Regular", "Regular", "Decaf", "Regular", "Regular", "D…
## $ 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…

2.2 Deskripsi Variabel Kunci

Deskripsi variabel utama dalam dataset Coffee Chain
Variabel Deskripsi
Sales Pendapatan kotor dari penjualan produk (USD)
Profit Keuntungan bersih setelah dikurangi seluruh biaya (USD)
Margin Selisih antara harga jual dan COGS (USD)
COGS Cost of Goods Sold — biaya langsung produksi
Marketing Biaya pemasaran per transaksi (USD)
Total Expenses Total biaya operasional (Marketing + biaya lainnya)
Product Type Kategori produk: Coffee, Espresso, Tea, Herbal Tea
Market Wilayah pasar: Central, East, South, West
Market Size Ukuran pasar: Major Market / Small Market

3 Persiapan Data (Data Preparation)

3.1 Pembersihan dan Feature Engineering

df_clean <- df %>%
  # Hapus spasi tersembunyi pada kolom karakter
  mutate(across(where(is.character), str_trim)) %>%

  # Feature engineering: variabel turunan yang kaya informasi
  mutate(
    # Profit Margin Rate: efisiensi konversi sales ke profit
    Profit_Rate      = Profit / Sales * 100,

    # Expense Ratio: proporsi total biaya terhadap sales
    Expense_Ratio    = Total_Expenses / Sales * 100,

    # Marketing Efficiency: profit yang dihasilkan per 1 unit marketing spend
    Mktg_Efficiency  = Profit / Marketing,

    # Flag: apakah observasi menghasilkan profit negatif?
    Loss_Flag        = ifelse(Profit < 0, "Rugi", "Untung"),

    # Margin Rate: margin sebagai % dari sales
    Margin_Rate      = Margin / Sales * 100
  )

cat("Jumlah observasi dengan profit negatif:", sum(df_clean$Profit < 0), "\n")
## Jumlah observasi dengan profit negatif: 528
cat("Proporsi rugi:", round(mean(df_clean$Profit < 0) * 100, 1), "%\n")
## Proporsi rugi: 12.4 %
# Statistik deskriptif variabel numerik utama
df_clean %>%
  select(Sales, Profit, Margin, COGS, Marketing, Total_Expenses, Profit_Rate) %>%
  summary() %>%
  kable(caption = "Statistik deskriptif variabel numerik utama")
Statistik deskriptif variabel numerik utama
Sales Profit Margin COGS Marketing Total_Expenses Profit_Rate
Min. : 17 Min. :-638.0 Min. :-302.00 Min. : 0.00 Min. : 0.00 Min. : 10.00 Min. :-3190.00
1st Qu.:100 1st Qu.: 17.0 1st Qu.: 52.75 1st Qu.: 43.00 1st Qu.: 13.00 1st Qu.: 33.00 1st Qu.: 16.09
Median :138 Median : 40.0 Median : 76.00 Median : 60.00 Median : 22.00 Median : 46.00 Median : 32.00
Mean :193 Mean : 61.1 Mean : 104.29 Mean : 84.43 Mean : 31.19 Mean : 54.06 Mean : 14.72
3rd Qu.:230 3rd Qu.: 92.0 3rd Qu.: 132.00 3rd Qu.:100.00 3rd Qu.: 39.00 3rd Qu.: 65.00 3rd Qu.: 42.78
Max. :912 Max. : 778.0 Max. : 613.00 Max. :364.00 Max. :156.00 Max. :190.00 Max. : 118.08

Catatan interpretatif: Nilai minimum Profit sebesar -638 USD dan rata-rata Profit_Rate yang tidak homogen antar kelompok mengindikasikan adanya inefisiensi struktural pada segmen tertentu. Hal ini akan ditelaah lebih dalam pada bagian analisis.


4 Exploratory Data Analysis (EDA)

4.1 Profitabilitas per Kategori Produk

profit_by_type <- df_clean %>%
  group_by(Product_Type) %>%
  summarise(
    Total_Sales    = sum(Sales),
    Total_Profit   = sum(Profit),
    Avg_Profit_Rate = mean(Profit_Rate),
    Pct_Loss       = mean(Loss_Flag == "Rugi") * 100,
    n              = n(),
    .groups = "drop"
  ) %>%
  arrange(desc(Avg_Profit_Rate))

kable(profit_by_type %>%
        mutate(across(where(is.numeric), ~round(., 2))),
      caption = "Ringkasan profitabilitas per kategori produk")
Ringkasan profitabilitas per kategori produk
Product_Type Total_Sales Total_Profit Avg_Profit_Rate Pct_Loss n
Herbal Tea 207214 63254 24.98 11.93 1056
Coffee 216828 74683 24.02 12.88 1056
Espresso 222996 68620 21.66 12.59 1176
Tea 172773 52986 -15.31 12.29 960

4.2 Profitabilitas per Wilayah Pasar

profit_by_market <- df_clean %>%
  group_by(Market) %>%
  summarise(
    Total_Sales    = sum(Sales),
    Total_Profit   = sum(Profit),
    Avg_Profit_Rate = mean(Profit_Rate),
    Pct_Loss       = mean(Loss_Flag == "Rugi") * 100,
    .groups = "drop"
  ) %>%
  arrange(desc(Avg_Profit_Rate))

kable(profit_by_market %>%
        mutate(across(where(is.numeric), ~round(., 2))),
      caption = "Ringkasan profitabilitas per wilayah pasar")
Ringkasan profitabilitas per wilayah pasar
Market Total_Sales Total_Profit Avg_Profit_Rate Pct_Loss
Central 265045 93852 30.43 10.27
South 103926 32478 27.19 11.01
East 178576 59217 17.19 15.09
West 272264 73996 -8.87 13.54

Temuan awal yang krusial: Kategori Tea memiliki rata-rata Profit Rate sebesar -15.31% — artinya secara rata-rata setiap transaksi Tea justru menghabiskan uang, bukan menghasilkan. Demikian pula wilayah West dengan Profit Rate -8.87%. Ini adalah sinyal inefisiensi yang perlu pendalaman kuantitatif.


5 Visualisasi Data

5.1 Visualisasi 1: Profit Rate per Kategori Produk dan Wilayah (Heatmap)

heatmap_data <- df_clean %>%
  group_by(Product_Type, Market) %>%
  summarise(Avg_Profit_Rate = mean(Profit_Rate), .groups = "drop")

ggplot(heatmap_data, aes(x = Market, y = Product_Type, fill = Avg_Profit_Rate)) +
  geom_tile(color = "white", linewidth = 0.8) +
  geom_text(aes(label = paste0(round(Avg_Profit_Rate, 1), "%")),
            color = "white", fontface = "bold", size = 4.5) +
  scale_fill_gradient2(
    low      = "#c0392b",
    mid      = "#f39c12",
    high     = "#27ae60",
    midpoint = 0,
    name     = "Profit Rate (%)"
  ) +
  labs(
    title    = "Rata-rata Profit Rate per Kombinasi Kategori Produk dan Wilayah Pasar",
    subtitle = "Merah = profit negatif (rugi) | Hijau = profit positif",
    x        = "Wilayah Pasar",
    y        = "Kategori Produk",
    caption  = "Sumber: Coffee Chain Dataset"
  ) +
  theme_minimal(base_size = 12) +
  theme(
    plot.title    = element_text(face = "bold", size = 13),
    plot.subtitle = element_text(color = "grey40"),
    legend.position = "right"
  )

Interpretasi: Heatmap ini mengungkapkan pola yang tidak terlihat dari laporan agregat biasa. Kombinasi yang paling mengkhawatirkan adalah Tea di West (-98.3%) — artinya setiap transaksi Tea di wilayah West rata-rata menghasilkan kerugian hampir setara nilai penjualannya sendiri. Satu-satunya kombinasi lain yang merugi adalah Espresso di East (-26.1%). Di sisi positif, Coffee di East (46.6%) dan Tea di East (46.5%) adalah dua kombinasi paling menguntungkan, diikuti Espresso di Central (40.1%). Temuan ini menunjukkan bahwa masalah profitabilitas bersifat spesifik segmen, tidak merata — dan wilayah West pada kategori Tea memerlukan perhatian manajerial segera.

5.2 Visualisasi 2: Hubungan Sales vs Profit — Mengekspos “Sales Tinggi, Profit Rendah”

df_clean %>%
  group_by(Product, Product_Type) %>%
  summarise(
    Avg_Sales  = mean(Sales),
    Avg_Profit = mean(Profit),
    Avg_Rate   = mean(Profit_Rate),
    .groups = "drop"
  ) %>%
  ggplot(aes(x = Avg_Sales, y = Avg_Profit, color = Product_Type, size = abs(Avg_Rate))) +
  geom_point(alpha = 0.8) +
  geom_hline(yintercept = 0, linetype = "dashed", color = "red", linewidth = 0.8) +
  geom_vline(xintercept = mean(df_clean$Sales), linetype = "dotted", color = "grey40") +
  geom_smooth(aes(group = 1), method = "lm", se = TRUE,
              color = "steelblue", linetype = "dashed", linewidth = 0.7, alpha = 0.15) +
  geom_text(aes(label = Product), size = 2.7, vjust = -1, hjust = 0.5, show.legend = FALSE) +
  scale_color_manual(values = c("Coffee" = "#e67e22", "Espresso" = "#8e44ad",
                                "Tea" = "#27ae60", "Herbal Tea" = "#2980b9")) +
  scale_size_continuous(range = c(2, 8), guide = "none") +
  labs(
    title    = "Scatterplot Sales vs Profit per Produk",
    subtitle = "Titik di bawah garis merah = produk yang secara rata-rata mengalami KERUGIAN",
    x        = "Rata-rata Sales (USD)",
    y        = "Rata-rata Profit (USD)",
    color    = "Kategori Produk",
    caption  = "Sumber: Coffee Chain Dataset | Ukuran titik ∝ |Profit Rate|"
  ) +
  theme_minimal(base_size = 12) +
  theme(
    plot.title    = element_text(face = "bold", size = 13),
    plot.subtitle = element_text(color = "grey40"),
    legend.position = "bottom"
  )

Interpretasi: Visualisasi ini membuktikan hipotesis utama: beberapa produk memiliki sales yang tidak rendah namun tetap menghasilkan profit negatif. Produk Earl Grey dan Lemon (kategori Tea dan Herbal Tea) berada di bawah garis merah — kondisi ini bukan sekadar kebetulan, melainkan mencerminkan struktur biaya yang bermasalah. Sementara itu, produk-produk Espresso seperti Caffe Mocha dan Regular Espresso konsisten berada di kuadran atas, mengonfirmasi bahwa kategori ini adalah cash cow perusahaan.

5.3 Visualisasi 3: Distribusi Profit Rate per Kategori Produk (Violin + Boxplot)

ggplot(df_clean, aes(x = reorder(Product_Type, Profit_Rate, FUN = median),
                     y = Profit_Rate, fill = Product_Type)) +
  geom_violin(alpha = 0.6, trim = FALSE) +
  geom_boxplot(width = 0.15, alpha = 0.9, outlier.size = 0.5) +
  geom_hline(yintercept = 0, linetype = "dashed", color = "red", linewidth = 0.8) +
  scale_fill_manual(values = c("Coffee" = "#e67e22", "Espresso" = "#8e44ad",
                                "Tea" = "#27ae60", "Herbal Tea" = "#2980b9")) +
  coord_flip() +
  labs(
    title    = "Distribusi Profit Rate per Kategori Produk",
    subtitle = "Garis merah = titik impas (Profit Rate = 0%)",
    x        = "Kategori Produk",
    y        = "Profit Rate (%)",
    fill     = "Kategori",
    caption  = "Sumber: Coffee Chain Dataset"
  ) +
  theme_minimal(base_size = 12) +
  theme(
    plot.title    = element_text(face = "bold", size = 13),
    plot.subtitle = element_text(color = "grey40"),
    legend.position = "none"
  )

Interpretasi: Violin plot mengungkapkan tidak hanya perbedaan rata-rata, tetapi juga variabilitas profit rate antar kategori. Kategori Tea memiliki distribusi yang sangat lebar dan condong ke bawah garis merah, menandakan ketidakstabilan profitabilitas yang ekstrem. Espresso memiliki distribusi yang lebih padat di area positif, mencerminkan konsistensi kinerja yang baik. Coffee dan Herbal Tea menunjukkan pola bimodal — ada kelompok yang sangat menguntungkan dan ada yang justru merugi dalam kategori yang sama.


6 Analisis Statistik

6.1 Analisis Korelasi Antar Variabel Numerik

num_vars <- df_clean %>%
  select(Sales, Profit, Margin, COGS, Marketing, Total_Expenses, Profit_Rate, Margin_Rate)

cor_matrix <- cor(num_vars, use = "complete.obs")

# Tampilkan sebagai tabel
kable(round(cor_matrix, 3),
      caption = "Matriks korelasi Pearson antar variabel numerik")
Matriks korelasi Pearson antar variabel numerik
Sales Profit Margin COGS Marketing Total_Expenses Profit_Rate Margin_Rate
Sales 1.000 0.797 0.939 0.887 0.711 0.689 0.139 0.087
Profit 0.797 1.000 0.921 0.465 0.225 0.200 0.520 0.445
Margin 0.939 0.921 1.000 0.679 0.532 0.521 0.372 0.331
COGS 0.887 0.465 0.679 1.000 0.818 0.783 -0.194 -0.246
Marketing 0.711 0.225 0.532 0.818 1.000 0.966 -0.251 -0.247
Total_Expenses 0.689 0.200 0.521 0.783 0.966 1.000 -0.252 -0.235
Profit_Rate 0.139 0.520 0.372 -0.194 -0.251 -0.252 1.000 0.973
Margin_Rate 0.087 0.445 0.331 -0.246 -0.247 -0.235 0.973 1.000
# Visualisasi korelasi — pakai tidyr (sudah ada dalam tidyverse)
cor_melt <- cor_matrix %>%
  as.data.frame() %>%
  rownames_to_column("Var1") %>%
  pivot_longer(-Var1, names_to = "Var2", values_to = "value")

ggplot(cor_melt, aes(x = Var1, y = Var2, fill = value)) +
  geom_tile(color = "white") +
  geom_text(aes(label = round(value, 2)), size = 3.2, color = "white", fontface = "bold") +
  scale_fill_gradient2(low = "#c0392b", mid = "white", high = "#2980b9",
                       midpoint = 0, limits = c(-1, 1), name = "Korelasi") +
  labs(
    title    = "Heatmap Matriks Korelasi",
    subtitle = "Korelasi Pearson | nilai mendekati ±1 = hubungan kuat",
    x = NULL, y = NULL,
    caption  = "Sumber: Coffee Chain Dataset"
  ) +
  theme_minimal(base_size = 11) +
  theme(
    axis.text.x   = element_text(angle = 45, hjust = 1),
    plot.title    = element_text(face = "bold"),
    plot.subtitle = element_text(color = "grey40")
  )

Interpretasi korelasi:

  • Margin → Profit (r = 0.921): Korelasi sangat kuat positif — Margin adalah prediktor dominan profit, jauh melampaui variabel lainnya.
  • Sales → Profit (r = 0.797): Kuat, namun lebih rendah dari Margin. Sales saja tidak cukup menjamin profit.
  • Profit_Rate → Profit (r = 0.520): Cukup kuat — efisiensi konversi sales ke profit berpengaruh signifikan terhadap profit absolut.
  • Marketing → Profit (r = 0.225): Korelasi lemah — pengeluaran marketing tidak berbanding lurus dengan profit, mengindikasikan inefisiensi alokasi anggaran pemasaran.
  • COGS → Profit_Rate (r = -0.194): Negatif — semakin tinggi biaya produksi, semakin rendah efisiensi profit rate, konsisten dengan logika bisnis.

6.2 Regresi Linear Sederhana: Profit ~ Sales

model_simple <- lm(Profit ~ Sales, data = df_clean)
summary(model_simple)
## 
## Call:
## lm(formula = Profit ~ Sales, data = df_clean)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -606.28   -9.15   11.77   28.31  466.85 
## 
## Coefficients:
##               Estimate Std. Error t value Pr(>|t|)    
## (Intercept) -42.456004   1.527850  -27.79   <2e-16 ***
## Sales         0.536582   0.006233   86.08   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 61.39 on 4246 degrees of freedom
## Multiple R-squared:  0.6357, Adjusted R-squared:  0.6357 
## F-statistic:  7410 on 1 and 4246 DF,  p-value: < 2.2e-16

Interpretasi Regresi Sederhana:

Berdasarkan output R, model menghasilkan:

  • Intercept (β₀ = -42.456): Ketika Sales = 0, estimasi profit adalah -42.46 USD — mencerminkan adanya biaya tetap yang harus ditanggung bahkan tanpa penjualan.
  • Koefisien Sales (β₁ = 0.537, p < 0.001): Setiap kenaikan 1 USD Sales diasosiasikan dengan kenaikan profit sebesar 0.537 USD. Koefisien ini sangat signifikan secara statistik (t = 86.08).
  • R² = 0.6357: Sales mampu menjelaskan 63.57% variasi profit. Namun 36.43% sisanya tidak dapat dijelaskan oleh Sales saja — mengonfirmasi bahwa Sales bukan satu-satunya penentu profitabilitas.

6.3 Regresi Linear Berganda: Profit ~ Sales + Margin

model_multi <- lm(Profit ~ Sales + Margin, data = df_clean)
summary(model_multi)
## 
## Call:
## lm(formula = Profit ~ Sales + Margin, data = df_clean)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -185.53  -14.70    2.55   19.43  161.73 
## 
## Coefficients:
##              Estimate Std. Error t value Pr(>|t|)    
## (Intercept) -28.68947    0.86939  -33.00   <2e-16 ***
## Sales        -0.37973    0.01016  -37.39   <2e-16 ***
## Margin        1.56357    0.01627   96.09   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 34.46 on 4245 degrees of freedom
## Multiple R-squared:  0.8853, Adjusted R-squared:  0.8852 
## F-statistic: 1.638e+04 on 2 and 4245 DF,  p-value: < 2.2e-16
# Tabel perbandingan model
comp_df <- data.frame(
  Model      = c("Regresi Sederhana (Profit ~ Sales)",
                 "Regresi Berganda (Profit ~ Sales + Margin)"),
  R_squared  = c(round(summary(model_simple)$r.squared, 4),
                 round(summary(model_multi)$r.squared, 4)),
  Adj_R2     = c(round(summary(model_simple)$adj.r.squared, 4),
                 round(summary(model_multi)$adj.r.squared, 4)),
  RMSE       = c(round(sqrt(mean(residuals(model_simple)^2)), 2),
                 round(sqrt(mean(residuals(model_multi)^2)), 2))
)
kable(comp_df, caption = "Perbandingan performa model regresi")
Perbandingan performa model regresi
Model R_squared Adj_R2 RMSE
Regresi Sederhana (Profit ~ Sales) 0.6357 0.6357 61.38
Regresi Berganda (Profit ~ Sales + Margin) 0.8853 0.8852 34.44

Interpretasi Regresi Berganda:

Berdasarkan output R, penambahan variabel Margin menghasilkan perubahan dramatis:

  • Koefisien Sales (β₁ = -0.380, p < 0.001): Setelah Margin dikontrol, Sales justru berpengaruh negatif terhadap profit. Ini mengungkapkan bahwa “efek positif Sales” pada model sederhana sebelumnya sebagian besar adalah efek Margin yang berjalan bersamaan — bukan murni efek volume penjualan.
  • Koefisien Margin (β₂ = 1.564, p < 0.001): Setiap kenaikan 1 USD Margin meningkatkan profit sebesar 1.564 USD, jauh lebih besar dari pengaruh Sales. Ini adalah bukti kuantitatif terkuat bahwa Margin adalah penentu utama profitabilitas.
  • R² meningkat dari 0.6357 → 0.8853: Penambahan Margin meningkatkan daya jelasnya sebesar +24.96 poin persentase.
  • RMSE turun dari 61.38 → 34.44: Kesalahan prediksi berkurang hampir separuhnya, menandakan model berganda jauh lebih akurat.

Kesimpulan regresi: Terbukti bahwa dalam konteks Coffee Chain, margin per unit produk jauh lebih menentukan profit dibandingkan volume penjualan. Strategi bisnis yang hanya mengejar peningkatan sales tanpa memperhatikan struktur margin berisiko memperburuk profitabilitas secara keseluruhan.

6.4 Uji Asumsi Regresi Berganda

par(mfrow = c(1, 2))
plot(model_multi, which = c(1, 2), main = "")

par(mfrow = c(1, 1))

Interpretasi diagnostik: Plot residual membantu memverifikasi asumsi linearitas dan normalitas. Penyimpangan yang teridentifikasi pada titik ekstrem konsisten dengan adanya outlier pada segmen Tea-West yang telah diidentifikasi sebelumnya.


7 Segmentasi dan Clustering

7.1 Segmentasi Berbasis Kinerja (Sales × Profit)

# Segmentasi produk berdasarkan kombinasi Sales dan Profit relatif terhadap median
med_sales  <- median(df_clean$Sales)
med_profit <- median(df_clean$Profit)

df_seg <- df_clean %>%
  mutate(
    Segment = case_when(
      Sales >= med_sales & Profit >= med_profit ~ "Star (Sales Tinggi, Profit Tinggi)",
      Sales >= med_sales & Profit <  med_profit ~ "Drainer (Sales Tinggi, Profit Rendah)",
      Sales <  med_sales & Profit >= med_profit ~ "Niche (Sales Rendah, Profit Tinggi)",
      TRUE                                      ~ "Weak (Sales Rendah, Profit Rendah)"
    )
  )

# Ringkasan per segmen
seg_summary <- df_seg %>%
  group_by(Segment) %>%
  summarise(
    N           = n(),
    Avg_Sales   = round(mean(Sales), 1),
    Avg_Profit  = round(mean(Profit), 1),
    Avg_Rate    = round(mean(Profit_Rate), 1),
    Pct_Total   = round(n() / nrow(df_seg) * 100, 1),
    .groups = "drop"
  ) %>%
  arrange(desc(Avg_Profit))

kable(seg_summary, caption = "Ringkasan statistik per segmen kinerja")
Ringkasan statistik per segmen kinerja
Segment N Avg_Sales Avg_Profit Avg_Rate Pct_Total
Star (Sales Tinggi, Profit Tinggi) 1715 316.7 138.3 42.4 40.4
Niche (Sales Rendah, Profit Tinggi) 448 110.5 49.0 47.3 10.5
Drainer (Sales Tinggi, Profit Rendah) 412 186.1 1.0 -0.2 9.7
Weak (Sales Rendah, Profit Rendah) 1673 90.0 0.0 -18.7 39.4
ggplot(df_seg, aes(x = Sales, y = Profit, color = Segment)) +
  geom_point(alpha = 0.3, size = 1.5) +
  geom_hline(yintercept = med_profit, linetype = "dashed", color = "grey50") +
  geom_vline(xintercept = med_sales,  linetype = "dashed", color = "grey50") +
  geom_hline(yintercept = 0, color = "red", linewidth = 0.8) +
  scale_color_manual(values = c(
    "Star (Sales Tinggi, Profit Tinggi)"   = "#27ae60",
    "Drainer (Sales Tinggi, Profit Rendah)" = "#e74c3c",
    "Niche (Sales Rendah, Profit Tinggi)"  = "#3498db",
    "Weak (Sales Rendah, Profit Rendah)"   = "#95a5a6"
  )) +
  annotate("text", x = max(df_seg$Sales)*0.85, y = max(df_seg$Profit)*0.85,
           label = "STAR", fontface = "bold", color = "#27ae60", size = 5) +
  annotate("text", x = max(df_seg$Sales)*0.85, y = min(df_seg$Profit)*0.85,
           label = "DRAINER", fontface = "bold", color = "#e74c3c", size = 5) +
  labs(
    title    = "Peta Segmentasi Kinerja: Sales vs Profit",
    subtitle = "Garis merah = titik impas | Garis abu = nilai median",
    x        = "Sales (USD)",
    y        = "Profit (USD)",
    color    = "Segmen",
    caption  = "Sumber: Coffee Chain Dataset"
  ) +
  theme_minimal(base_size = 12) +
  theme(
    plot.title    = element_text(face = "bold"),
    plot.subtitle = element_text(color = "grey40"),
    legend.position = "bottom",
    legend.text   = element_text(size = 8)
  )

Interpretasi segmentasi: Dari tabel, segmen Star (40.4% transaksi) adalah mesin profit utama dengan Profit Rate rata-rata 42.4%. Segmen Niche meski volume kecil memiliki Profit Rate tertinggi (47.3%) — produk-produk ini efisien dan layak dikembangkan. Yang paling kritis adalah segmen Drainer (9.7% transaksi): Sales-nya di atas median (186.1 USD) namun Profit Rate hampir nol (-0.2%) — biaya operasional yang dikeluarkan untuk mendukung volume tinggi ini tidak terbayar oleh profit yang memadai. Segmen Weak (39.4%) dengan Profit Rate -18.7% adalah segmen paling merugi secara rata-rata.

7.2 K-Means Clustering

set.seed(42)

# Persiapan data clustering
cluster_data <- df_clean %>%
  select(Sales, Profit, Margin, Marketing) %>%
  scale() %>%
  as.data.frame()

# Menentukan jumlah kluster optimal dengan Elbow Method
wss <- sapply(1:8, function(k) {
  kmeans(cluster_data, centers = k, nstart = 25)$tot.withinss
})

elbow_df <- data.frame(k = 1:8, WSS = wss)

ggplot(elbow_df, aes(x = k, y = WSS)) +
  geom_line(color = "steelblue", linewidth = 1) +
  geom_point(color = "steelblue", size = 3) +
  geom_vline(xintercept = 3, linetype = "dashed", color = "red") +
  annotate("text", x = 3.2, y = max(wss)*0.85, label = "k = 3 optimal",
           color = "red", hjust = 0) +
  labs(
    title = "Elbow Method untuk Menentukan Jumlah Kluster Optimal",
    x = "Jumlah Kluster (k)",
    y = "Within-Cluster Sum of Squares (WSS)"
  ) +
  theme_minimal(base_size = 12) +
  theme(plot.title = element_text(face = "bold"))

# Fit k-means dengan k = 3
km_model <- kmeans(cluster_data, centers = 3, nstart = 50)

df_cluster <- df_clean %>%
  mutate(Cluster = factor(km_model$cluster))

# Karakteristik tiap kluster
cluster_profile <- df_cluster %>%
  group_by(Cluster) %>%
  summarise(
    N           = n(),
    Avg_Sales   = round(mean(Sales), 1),
    Avg_Profit  = round(mean(Profit), 1),
    Avg_Margin  = round(mean(Margin), 1),
    Avg_Mktg    = round(mean(Marketing), 1),
    Avg_Rate    = round(mean(Profit_Rate), 1),
    .groups = "drop"
  ) %>%
  mutate(
    Label = case_when(
      Avg_Sales == max(Avg_Sales) ~ "Kluster Unggulan",
      Avg_Profit == min(Avg_Profit) ~ "Kluster Bermasalah",
      TRUE ~ "Kluster Menengah"
    )
  )

kable(cluster_profile,
      caption = "Profil karakteristik tiap kluster K-Means (k=3)")
Profil karakteristik tiap kluster K-Means (k=3)
Cluster N Avg_Sales Avg_Profit Avg_Margin Avg_Mktg Avg_Rate Label
1 406 581.6 267.0 328.7 79.3 45.2 Kluster Unggulan
2 1165 253.3 96.6 142.6 41.3 37.3 Kluster Menengah
3 2677 107.8 14.4 53.6 19.5 0.3 Kluster Bermasalah
ggplot(df_cluster, aes(x = Sales, y = Profit, color = Cluster)) +
  geom_point(alpha = 0.35, size = 1.5) +
  geom_hline(yintercept = 0, color = "red", linewidth = 0.8, linetype = "dashed") +
  scale_color_manual(values = c("1" = "#27ae60", "2" = "#e74c3c", "3" = "#f39c12"),
                     labels = cluster_profile$Label) +
  labs(
    title   = "Visualisasi Hasil K-Means Clustering (k = 3)",
    subtitle = "Garis merah = titik impas profitabilitas",
    x = "Sales (USD)", y = "Profit (USD)",
    color = "Kluster",
    caption = "Sumber: Coffee Chain Dataset"
  ) +
  theme_minimal(base_size = 12) +
  theme(
    plot.title    = element_text(face = "bold"),
    plot.subtitle = element_text(color = "grey40"),
    legend.position = "right"
  )

Interpretasi clustering: K-Means berhasil memisahkan observasi ke dalam tiga kluster yang bermakna secara bisnis. Kluster Unggulan (n=406) memiliki rata-rata Sales 581.6 USD dan Profit 267.0 USD dengan Profit Rate 45.2% — ini adalah transaksi-transaksi bervolume besar sekaligus sangat efisien. Kluster Menengah (n=1.165) beroperasi dengan Profit Rate 37.3%, cukup sehat namun dengan skala lebih kecil. Kluster Bermasalah (n=2.677, mayoritas 63% data) memiliki rata-rata Profit Rate hanya 0.3% — hampir tidak menghasilkan profit sama sekali meski tetap beroperasi. Kluster ini yang paling mendesak untuk dievaluasi struktur biayanya.


8 Insight Bisnis

8.1 Temuan Utama

Berdasarkan seluruh rangkaian analisis, terdapat lima temuan utama yang memiliki implikasi langsung terhadap pengambilan keputusan bisnis:

1. Margin adalah penentu profit yang lebih kuat daripada Sales. Hasil regresi berganda membuktikan ini secara kuantitatif: koefisien Margin = 1.564 vs koefisien Sales = -0.380 (negatif setelah Margin dikontrol). Artinya, mengejar volume Sales tanpa memperbaiki Margin justru kontraproduktif — setiap 1 USD tambahan Sales yang tidak diikuti peningkatan Margin berpotensi mengurangi profit.

2. Kategori Tea adalah profit destroyer terbesar. Dengan rata-rata Profit Rate -15.31%, Tea adalah satu-satunya kategori yang secara agregat merugi. Ketika dipersempit ke level wilayah, kombinasi Tea di West mencapai -98.3% — artinya setiap 100 USD yang terjual di segmen ini menghasilkan kerugian hampir 100 USD. Ini adalah prioritas intervensi tertinggi.

3. Wilayah West mengalami inefisiensi sistemik. West adalah satu-satunya wilayah dengan Profit Rate agregat negatif (-8.87%), meski memiliki total sales tertinggi kedua (272.264 USD). Paradoks ini — sales besar namun profit negatif — mengindikasikan bahwa ada faktor struktural seperti biaya distribusi lebih tinggi, margin produk yang lebih tertekan, atau bauran produk yang tidak optimal di wilayah ini.

4. Marketing spend tidak berkorelasi dengan profit (r = 0.225). Temuan ini mengindikasikan adanya misalokasi anggaran pemasaran. Kemungkinan besar pengeluaran marketing terbesar justru dialokasikan ke segmen yang secara struktural tidak menguntungkan (Tea-West), sehingga efeknya tidak terkonversi menjadi profit.

5. Espresso adalah kategori paling konsisten menguntungkan. Dengan distribusi Profit Rate yang stabil di atas nol dan variabilitas rendah, kategori Espresso — terutama Caffe Mocha dan Regular Espresso — adalah cash cow yang perlu dijaga dan diperluas kapasitasnya, bukan dikanibal oleh diversifikasi produk yang tidak menguntungkan.

8.2 Rekomendasi Strategis

Matriks rekomendasi strategis berbasis temuan analisis
Prioritas Area Rekomendasi
🔴 Tinggi Produk Tea Lakukan audit biaya menyeluruh pada kategori Tea. Pertimbangkan repricing atau discontinuation pada varian yang defisit kronis (Earl Grey, Lemon).
🔴 Tinggi Wilayah West Investigasi struktur biaya wilayah West. Evaluasi apakah ada peluang renegoisasi kontrak distribusi atau penyesuaian portofolio produk.
🟡 Menengah Alokasi Marketing Realokasikan anggaran marketing dari segmen Tea-West ke Espresso-Central/South yang terbukti menghasilkan ROI lebih tinggi.
🟡 Menengah Harga Tea Naikkan harga jual produk Tea minimal 15–20% untuk menutup gap margin, atau lakukan efisiensi COGS melalui renegosiasi pemasok.
🟢 Oportunitas Ekspansi Espresso Tingkatkan ketersediaan dan promosi Espresso di wilayah South dan Central yang menunjukkan Profit Rate tertinggi.

9 Kesimpulan

Laporan ini telah melakukan analisis profitabilitas komprehensif terhadap 4.248 catatan transaksi Coffee Chain menggunakan pendekatan multimetode — korelasi, regresi, segmentasi, dan clustering.

Kesimpulan utama yang dapat ditarik adalah:

  1. Hubungan Sales-Profit tidak linear dan tidak universal. Terdapat segmen-segmen spesifik di mana peningkatan sales justru disertai pemborosan biaya yang lebih besar, menghasilkan profit negatif.

  2. Margin adalah variabel kunci yang harus menjadi fokus utama manajemen, bukan hanya laporan penjualan. Peningkatan 1 USD dalam Margin memiliki dampak lebih besar terhadap profit dibandingkan peningkatan 1 USD dalam Sales.

  3. Inefisiensi bersifat terkonsentrasi, bukan merata — kategori Tea dan wilayah West adalah dua kutub masalah yang perlu penanganan segera dan berbeda dari strategi bisnis keseluruhan.

  4. K-Means clustering berhasil mengidentifikasi tiga kluster bisnis yang bermakna operasional: kluster unggulan, menengah, dan bermasalah — memberikan dasar objektif bagi alokasi sumber daya dan prioritas intervensi manajerial.

Dengan memahami dinamika ini secara kuantitatif, manajemen Coffee Chain dapat bergeser dari pengambilan keputusan berbasis intuisi menuju keputusan berbasis bukti (evidence-based decision making) yang lebih akuntabel dan berdampak nyata pada bottom line perusahaan.