1. Deskripsi Insight

1.1 Latar Belakang

Dataset yang digunakan dalam laporan ini adalah Coffee Chain Dataset yang berisi data transaksi penjualan produk kopi dari berbagai wilayah di Amerika Serikat, mencakup 4.248 observasi dengan 20 variabel. Dataset ini memuat informasi seputar produk, wilayah pemasaran, biaya produksi, pengeluaran marketing, margin, hingga profit aktual dan anggaran.

Sebagai dataset pendamping, digunakan US Household Income Statistics (sumber: Kaggle — US Household Income Stats & Geo Locations) yang berisi data pendapatan rumah tangga dari lebih dari 32.000 lokasi di Amerika Serikat dan akan diringkas ke tingkat negara bagian (state).

1.2 Insight yang Diambil

“Apa sebenarnya yang paling menentukan profit di bisnis Coffee Chain? Apakah cukup dengan meningkatkan marketing, atau justru faktor internal seperti efisiensi yang lebih berperan? Selain itu, apakah kondisi daya beli masyarakat di suatu negara bagian ikut memengaruhi hasil tiap transaksi?”

Insight ini diangkat karena beberapa temuan menarik dari eksplorasi data awal:

  1. Green Tea adalah satu-satunya produk dengan total profit negatif dari seluruh produk yang ada.
  2. Variabel marketing berkorelasi rendah dengan profit, padahal secara logika bisnis marketing seharusnya mendorong profit.
  3. Variabel margin berkorelasi sangat kuat dengan profit, mengindikasikan efisiensi operasional jauh lebih penting dari besarnya pengeluaran marketing.
  4. Terdapat variasi profit yang sangat besar antar negara bagian, dengan California sebagai yang tertinggi dan New Mexico terendah.
  5. Distribusi profit bersifat right-skewed dengan outlier ekstrem (profit negatif hingga -638), yang mengindikasikan perlunya transformasi data untuk membangun model regresi yang lebih robust.

1.3 Tujuan Analisis

  1. Mengidentifikasi produk dan wilayah dengan performa profit terbaik dan terburuk.
  2. Memahami hubungan antara variabel finansial internal (margin, sales, marketing, cogs, total_expenses) terhadap profit melalui korelasi dan regresi berganda.
  3. Menguji secara statistik apakah daya beli masyarakat (median_mean_income) sebagai variabel eksternal memiliki pengaruh signifikan terhadap profitabilitas Coffee Chain, baik melalui analisis korelasi di level state maupun sebagai prediktor dalam model regresi di level transaksi.
  4. Membangun dan membandingkan tiga model regresi dengan pendekatan berbeda, dari sederhana hingga paling robust secara statistik,untuk menemukan spesifikasi terbaik dalam memprediksi profit per transaksi.
  5. Membandingkan realisasi profit dengan anggaran (budget) yang telah ditetapkan per produk.

2. Persiapan Data

2.1 Load Library

library(dplyr)
library(ggplot2)
library(lubridate)
library(janitor)
library(tidyr)
library(corrplot)
library(scales)
library(gridExtra)
library(readxl)

2.2 Import Data

# Import Coffee Chain Dataset dari file XLSX (dataset utama dari SPADA UNS)
coffeetugas <- read_xlsx("C:/Users/Lenovo/Downloads/1. Tugas SIM 2025B - Coffee Chain Datasets/1. Tugas SIM 2025B - Coffee Chain Datasets.xlsx")
coffeetugas <- clean_names(coffeetugas)

# Import dataset pendamping: US Household Income Statistics
income <- read.csv("C:/Users/Lenovo/Downloads/archive (2)/kaggle_income.csv")
income <- clean_names(income)

2.3 Preprocessing Coffee Dataset

# Kolom date dari XLSX sudah bertipe POSIXct (cukup konversi ke Date)
coffeetugas$date  <- as.Date(coffeetugas$date)
coffeetugas$bulan <- floor_date(coffeetugas$date, "month")
coffeetugas$tahun <- year(coffeetugas$date)

# Normalisasi nama state ke huruf kecil untuk keamanan merge
coffeetugas$state <- tolower(trimws(coffeetugas$state))

cat("Dimensi data coffee :", nrow(coffeetugas), "baris x", ncol(coffeetugas), "kolom\n")
## Dimensi data coffee : 4248 baris x 22 kolom
cat("Rentang tanggal     :", as.character(min(coffeetugas$date)),
    "s.d.", as.character(max(coffeetugas$date)), "\n")
## Rentang tanggal     : 2012-01-01 s.d. 2013-12-01
cat("Jumlah missing value:", sum(is.na(coffeetugas)), "\n")
## Jumlah missing value: 0
cat("Jumlah negara bagian:", n_distinct(coffeetugas$state), "\n")
## Jumlah negara bagian: 20
cat("Jumlah produk       :", n_distinct(coffeetugas$product), "\n")
## Jumlah produk       : 13

2.4 Preprocessing Income Dataset

cat("Dimensi data income :", nrow(income), "baris x", ncol(income), "kolom\n")
## Dimensi data income : 32526 baris x 19 kolom
cat("Jumlah missing value:", sum(is.na(income)), "\n")
## Jumlah missing value: 0
# Normalisasi nama state ke huruf kecil agar merge tidak gagal diam-diam
income$state_name <- tolower(trimws(income$state_name))

# Agregasi per negara bagian menggunakan MEDIAN dari kolom Mean.
# Kolom 'mean' merepresentasikan rata-rata income per wilayah administratif kecil (place).
# Jika dirata-ratakan kembali (mean of mean), hasilnya bisa bias karena wilayah kecil
# dan miskin cenderung lebih banyak jumlahnya. Median lebih robust terhadap
# ketidakseimbangan distribusi jumlah wilayah antar state.
income_state <- income %>%
  group_by(state_name) %>%
  summarise(
    median_mean_income = median(mean,   na.rm = TRUE),
    median_income      = median(median, na.rm = TRUE),
    .groups = "drop"
  )

cat("\nRingkasan median_mean_income per negara bagian:\n")
## 
## Ringkasan median_mean_income per negara bagian:
print(summary(income_state$median_mean_income))
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   24382   54344   59471   62030   70123   91588

Catatan : Dalam analisis ini digunakan median sebagai representasi income per state, bukan rata-rata dari rata-rata. Alasannya untuk menghindari bias yang muncul akibat jumlah wilayah kecil (place) yang tidak seragam antar state. Median lebih robust terhadap distribusi yang skewed dan ketidakseimbangan jumlah observasi.

2.5 Cek Kompatibilitas State Sebelum Merge

state_coffee <- unique(coffeetugas$state)
state_income <- unique(income_state$state_name)

state_tidak_cocok <- setdiff(state_coffee, state_income)

cat("State di coffee yang TIDAK ada di income:\n")
## State di coffee yang TIDAK ada di income:
if (length(state_tidak_cocok) == 0) {
  cat("  --> Semua state cocok. Merge aman.\n")
} else {
  print(state_tidak_cocok)
}
##   --> Semua state cocok. Merge aman.

2.6 Penggabungan Dataset (Join)

# --- Join Level STATE (untuk visualisasi konteks dan analisis korelasi daya beli) ---
coffee_state <- coffeetugas %>%
  group_by(state, market) %>%
  summarise(
    total_profit     = sum(profit),
    total_sales      = sum(sales),
    total_cogs       = sum(cogs),
    total_margin     = sum(margin),
    avg_profit       = mean(profit),
    avg_marketing    = mean(marketing),
    jumlah_transaksi = n(),
    .groups = "drop"
  )

data_gabung <- coffee_state %>%
  left_join(income_state, by = c("state" = "state_name")) %>%
  na.omit()

cat("State berhasil di-merge :", nrow(data_gabung), "\n")
## State berhasil di-merge : 20
cat("Missing setelah merge   :", sum(is.na(data_gabung)), "\n\n")
## Missing setelah merge   : 0
knitr::kable(
  data_gabung %>%
    select(state, market, total_profit, median_mean_income, jumlah_transaksi) %>%
    arrange(desc(total_profit)),
  caption   = "Ringkasan Data Gabungan: Coffee Chain & Household Income per State",
  col.names = c("State", "Market", "Total Profit",
                "Median Mean Income (USD)", "Jumlah Transaksi")
)
Ringkasan Data Gabungan: Coffee Chain & Household Income per State
State Market Total Profit Median Mean Income (USD) Jumlah Transaksi
california West 31785 72331.5 288
illinois Central 30821 64024.0 216
iowa Central 22212 60311.0 216
new york East 20096 71152.5 192
colorado Central 17743 70118.5 264
massachusetts East 16442 83929.5 144
texas South 15766 59660.0 168
oregon West 12439 59333.0 264
florida East 12310 55946.0 216
washington West 11405 69906.5 240
ohio Central 10773 56121.0 216
nevada West 10616 62243.0 264
wisconsin Central 8702 61217.5 216
oklahoma South 8558 50914.5 168
utah West 7751 68554.0 288
connecticut East 7621 86702.0 168
louisiana South 7355 52979.0 168
missouri Central 3601 52084.0 216
new hampshire East 2748 75274.0 168
new mexico South 799 54767.0 168
# --- Join Level TRANSAKSI (untuk model regresi) ---
coffee_model <- coffeetugas %>%
  left_join(income_state, by = c("state" = "state_name")) %>%
  na.omit()

# Persiapan transformasi log untuk Model 3
# Karena profit bisa negatif, dilakukan shift agar seluruh nilai positif
min_profit   <- min(coffee_model$profit)
coffee_model <- coffee_model %>%
  mutate(profit_shifted = profit - min_profit + 1,
         log_profit     = log(profit_shifted))

cat("Dimensi data model  :", nrow(coffee_model), "baris x",
    ncol(coffee_model), "kolom\n")
## Dimensi data model  : 4248 baris x 26 kolom
cat("Nilai min profit    :", min_profit, "\n")
## Nilai min profit    : -638
cat("Rentang log_profit  :",
    round(min(coffee_model$log_profit), 3), "s.d.",
    round(max(coffee_model$log_profit), 3), "\n")
## Rentang log_profit  : 0 s.d. 7.256

Catatan : Karena terdapat nilai profit negatif (minimum = -638), transformasi log tidak bisa langsung diterapkan. Dilakukan shift terlebih dahulu: profit_shifted = profit - min(profit) + 1, sehingga seluruh nilai menjadi positif (minimum = 1) sebelum ditransformasi ke skala log. Ini adalah prosedur standar untuk menerapkan log-transform pada data yang mengandung nilai nol atau negatif.


3. Eksplorasi dan Visualisasi Data

3.1 Distribusi Profit per Transaksi

ggplot(coffeetugas, aes(x = profit)) +
  geom_histogram(bins = 40, fill = "#6F4E37", color = "white", alpha = 0.85) +
  geom_vline(xintercept = mean(coffeetugas$profit), color = "red",
             linetype = "dashed", linewidth = 1) +
  geom_vline(xintercept = median(coffeetugas$profit), color = "darkorange",
             linetype = "dashed", linewidth = 1) +
  annotate("text", x = mean(coffeetugas$profit) + 70, y = 300,
           label = paste0("Mean = ", round(mean(coffeetugas$profit), 1)),
           color = "red", size = 3.5) +
  annotate("text", x = median(coffeetugas$profit) - 90, y = 270,
           label = paste0("Median = ", round(median(coffeetugas$profit), 1)),
           color = "darkorange", size = 3.5) +
  labs(title    = "Distribusi Profit per Transaksi",
       subtitle = "Data Coffee Chain (4.248 observasi)",
       x = "Profit", y = "Frekuensi") +
  theme_minimal()

Interpretasi: Distribusi profit bersifat right-skewed (menjulur ke kanan). Mayoritas transaksi menghasilkan profit rendah hingga sedang, dengan mean 61.1 dan median 40. Selisih antara keduanya mengindikasikan adanya transaksi dengan profit sangat tinggi yang menarik rata-rata ke atas. Terdapat pula transaksi dengan profit sangat negatif (hingga -638). Skewness dan outlier ekstrem ini menjadi justifikasi utama diperlukannya Model 3 berbasis transformasi log.


3.2 Total Profit per Produk

profit_produk <- coffeetugas %>%
  group_by(product, product_type) %>%
  summarise(total_profit = sum(profit), .groups = "drop") %>%
  arrange(desc(total_profit))

ggplot(profit_produk,
       aes(x = reorder(product, total_profit),
           y = total_profit, fill = product_type)) +
  geom_col(alpha = 0.9) +
  geom_text(aes(label = comma(total_profit),
                hjust = ifelse(total_profit >= 0, -0.1, 1.1)), size = 3) +
  geom_hline(yintercept = 0, linewidth = 0.5, color = "black") +
  coord_flip() +
  scale_fill_brewer(palette = "Set2") +
  scale_y_continuous(labels = comma,
                     expand = expansion(mult = c(0.12, 0.15))) +
  labs(title    = "Total Profit berdasarkan Produk",
       subtitle = "Green Tea adalah satu-satunya produk dengan profit negatif",
       x = "Produk", y = "Total Profit", fill = "Tipe Produk") +
  theme_minimal() +
  theme(legend.position = "bottom")

Interpretasi: Colombian (Coffee) menjadi produk paling menguntungkan, diikuti Lemon (Tea) dan Decaf Espresso. Satu-satunya produk yang mengalami kerugian adalah Green Tea dengan total profit negatif sehingga perlu dievaluasi dari sisi harga jual, COGS, maupun permintaan pasar.


3.3 Total Profit per Negara Bagian

profit_state_viz <- coffeetugas %>%
  group_by(state, market) %>%
  summarise(total_profit = sum(profit), .groups = "drop") %>%
  arrange(desc(total_profit))

ggplot(profit_state_viz,
       aes(x = reorder(state, total_profit),
           y = total_profit, fill = market)) +
  geom_col(alpha = 0.9) +
  geom_text(aes(label = comma(total_profit)), hjust = -0.1, size = 2.8) +
  coord_flip() +
  scale_fill_brewer(palette = "Set1") +
  scale_y_continuous(labels = comma,
                     expand = expansion(mult = c(0, 0.15))) +
  labs(title    = "Total Profit berdasarkan Negara Bagian",
       subtitle = "Diwarnai berdasarkan wilayah market (Central / East / South / West)",
       x = "Negara Bagian", y = "Total Profit", fill = "Market Region") +
  theme_minimal() +
  theme(legend.position = "bottom")

Interpretasi: California (West) dan Illinois (Central) adalah dua negara bagian dengan profit tertinggi. New Mexico (South) merupakan yang terendah. Wilayah South secara konsisten menunjukkan performa lebih rendah dibanding wilayah lain.


3.4 Distribusi Profit per Market Region

ggplot(coffeetugas, aes(x = market, y = profit, fill = market)) +
  geom_boxplot(alpha = 0.8, outlier.color = "red", outlier.size = 1) +
  stat_summary(fun = mean, geom = "point", shape = 18,
               size = 3.5, color = "black") +
  scale_fill_brewer(palette = "Set1") +
  labs(title    = "Distribusi Profit per Market Region",
       subtitle = "Titik hitam = mean; titik merah = outlier",
       x = "Market Region", y = "Profit") +
  theme_minimal() +
  theme(legend.position = "none")

Interpretasi: Keempat market region memiliki distribusi profit yang serupa. Market West menunjukkan nilai median dan mean yang sedikit lebih tinggi. Adanya outlier negatif di semua region menunjukkan bahwa transaksi tidak menguntungkan bukan hanya terjadi di wilayah tertentu saja.


3.5 Heatmap Korelasi Variabel Numerik

num_data <- coffeetugas %>%
  select(budget_cogs, budget_margin, budget_profit,
         budget_sales, cogs, inventory, margin,
         marketing, profit, sales, total_expenses)

cor_matrix <- cor(num_data)

corrplot(cor_matrix,
         method      = "color",
         type        = "upper",
         addCoef.col = "black",
         number.cex  = 0.62,
         tl.cex      = 0.72,
         col         = colorRampPalette(c("#D73027", "white", "#1A9850"))(200),
         title       = "Heatmap Korelasi Variabel Numerik Coffee Chain",
         mar         = c(0, 0, 2, 0))

Interpretasi: Temuan utama dari heatmap korelasi:

  • marginprofit: r = 0.92. Hubungan sangat kuat dan positif, menunjukkan margin sebagai penentu utama profit.
  • budget_profitprofit: r = 0.94. Perencanaan anggaran berkorelasi erat dengan realisasi profit.
  • salesprofit: r = 0.8 . Hubungan kuat, volume penjualan berkontribusi langsung terhadap profit.
  • marketingprofit: r = 0.23 . Signifikan secara statistik, namun lemah secara praktis. Menunjukkan bahwa Marketing bukan penentu utama profit.
  • marketingtotal_expenses: r = 0.97 . Menunjukkan bahwa marketing adalah komponen dominan pengeluaran.
  • inventoryprofit: r = -0.09 . Hubungan negatif lemah, penumpukan stok tidak memberikan kontribusi terhadap profit.

3.6 Hubungan Median Income dan Total Profit per State

Bagian ini secara langsung menjawab pertanyaan utama insight: apakah daya beli masyarakat di suatu negara bagian berhubungan dengan profitabilitas Coffee Chain?

ggplot(data_gabung, aes(x = median_mean_income, y = total_profit)) +
  geom_point(aes(size = jumlah_transaksi, color = market), alpha = 0.8) +
  geom_smooth(method = "lm", se = TRUE, color = "black",
              linetype = "dashed", linewidth = 1) +
  geom_text(aes(label = state), vjust = -0.8, size = 2.8, color = "gray30") +
  scale_color_brewer(palette = "Set1") +
  scale_size_continuous(range = c(3, 10)) +
  scale_x_continuous(labels = comma) +
  scale_y_continuous(labels = comma) +
  labs(title    = "Hubungan Daya Beli (Income) dan Total Profit per State",
       subtitle = "Ukuran titik = jumlah transaksi; garis = tren regresi linear",
       x = "Median Mean Household Income (USD)",
       y = "Total Profit",
       color = "Market Region",
       size  = "Jumlah Transaksi") +
  theme_minimal() +
  theme(legend.position = "bottom")

Interpretasi: Scatter plot menunjukkan arah hubungan positif antara median_mean_income dan total_profit per state. Negara bagian dengan tingkat pendapatan rumah tangga lebih tinggi cenderung menghasilkan total profit lebih besar. Namun, sebaran titik yang cukup lebar mengindikasikan bahwa income bukan satu-satunya penentu: jumlah transaksi (ukuran titik) tampaknya juga berperan penting. Uji korelasi formal disajikan di Bagian 4.


3.7 Hubungan Margin dan Profit per Tipe Produk

ggplot(coffeetugas, aes(x = margin, y = profit, color = product_type)) +
  geom_point(alpha = 0.3, size = 1) +
  geom_smooth(method = "lm", se = FALSE, linewidth = 1.1) +
  scale_color_brewer(palette = "Dark2") +
  labs(title    = "Hubungan Margin dan Profit per Tipe Produk",
       subtitle = "Garis = tren regresi linear masing-masing tipe produk",
       x = "Margin", y = "Profit", color = "Tipe Produk") +
  theme_minimal() +
  theme(legend.position = "bottom")

Interpretasi: Hubungan linear positif yang sangat kuat antara margin dan profit konsisten di seluruh tipe produk. Kemiringan garis regresi hampir seragam, pengaruh margin terhadap profit tidak berbeda jauh antar tipe produk. Produk Espresso dan Coffee memiliki rentang nilai lebih lebar, sementara Herbal Tea lebih terkonsentrasi di nilai rendah.


3.8 Budget Profit vs Realisasi Profit per Produk

budget_vs_actual <- coffeetugas %>%
  group_by(product) %>%
  summarise(Realisasi = sum(profit),
            Anggaran  = sum(budget_profit),
            .groups   = "drop") %>%
  pivot_longer(cols = c(Realisasi, Anggaran),
               names_to = "Jenis", values_to = "Nilai")

ggplot(budget_vs_actual,
       aes(x = reorder(product, Nilai), y = Nilai, fill = Jenis)) +
  geom_col(position = "dodge", alpha = 0.9) +
  geom_hline(yintercept = 0, linewidth = 0.5) +
  coord_flip() +
  scale_fill_manual(values = c("Anggaran"  = "#AED6F1",
                               "Realisasi" = "#6F4E37")) +
  scale_y_continuous(labels = comma) +
  labs(title    = "Budget Profit vs Realisasi Profit per Produk",
       subtitle = "Biru = Anggaran; Coklat = Realisasi",
       x = "Produk", y = "Total Profit", fill = "") +
  theme_minimal() +
  theme(legend.position = "bottom")

Interpretasi: Hampir semua produk berhasil mencapai atau melampaui anggaran profit. Colombian mencatat realisasi jauh di atas anggaran. Green Tea adalah kasus kritis: tidak hanya gagal memenuhi anggaran, tetapi menghasilkan profit negatif yang mengindikasikan masalah fundamental pada penetapan harga atau biaya produksi.


3.9 Tren Profit Bulanan

tren_bulanan <- coffeetugas %>%
  group_by(bulan) %>%
  summarise(total_profit = sum(profit), .groups = "drop")

ggplot(tren_bulanan, aes(x = bulan, y = total_profit)) +
  geom_line(color = "#6F4E37", linewidth = 1.1) +
  geom_point(color = "#6F4E37", size = 2) +
  geom_smooth(method = "loess", se = TRUE, color = "steelblue",
              linetype = "dashed", alpha = 0.12) +
  scale_x_date(date_labels = "%b %Y", date_breaks = "3 months") +
  scale_y_continuous(labels = comma) +
  labs(title    = "Tren Total Profit per Bulan",
       subtitle = "Garis biru putus-putus = tren LOESS (smoothed)",
       x = "Bulan", y = "Total Profit") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

Interpretasi: Profit bulanan berfluktuasi namun secara keseluruhan relatif stabil. Garis tren LOESS menunjukkan kenaikan di awal-pertengahan periode dan sedikit penurunan di akhir. Fluktuasi tajam di beberapa bulan kemungkinan mencerminkan pengaruh musiman atau perubahan strategi pemasaran.


3.10 Distribusi Profit Asli vs Log-Transformed (Justifikasi Model 3)

p1 <- ggplot(coffee_model, aes(x = profit)) +
  geom_histogram(bins = 40, fill = "#6F4E37", color = "white", alpha = 0.85) +
  labs(title    = "Distribusi Profit Asli",
       subtitle = "Right-skewed, outlier ekstrem",
       x = "Profit", y = "Frekuensi") +
  theme_minimal()

p2 <- ggplot(coffee_model, aes(x = log_profit)) +
  geom_histogram(bins = 40, fill = "#2471A3", color = "white", alpha = 0.85) +
  labs(title    = "Distribusi Log(Profit Shifted)",
       subtitle = "Lebih simetris, mendekati normal",
       x = "log(profit_shifted)", y = "Frekuensi") +
  theme_minimal()

grid.arrange(p1, p2, ncol = 2)

Interpretasi: Distribusi profit asli (kiri) jelas right-skewed dengan ekor panjang dan outlier negatif ekstrem. Kondisi ini berpotensi melanggar asumsi normalitas residual dalam OLS. Setelah ditransformasi ke skala log (kanan), distribusinya jauh lebih simetris dan mendekati normal, sehingga asumsi regresi lebih terpenuhi dan estimasi koefisien lebih stabil.


4. Analisis Data

4.1 Uji Korelasi Pearson: Variabel Internal vs Profit

cat("=== Uji Korelasi Pearson: Variabel Prediktor vs Profit (n =",
    nrow(coffee_model), ") ===\n\n")
## === Uji Korelasi Pearson: Variabel Prediktor vs Profit (n = 4248 ) ===
vars_uji <- c("margin", "sales", "marketing", "cogs", "total_expenses")

for (v in vars_uji) {
  kor <- cor.test(coffee_model[[v]], coffee_model$profit, method = "pearson")
  cat(sprintf("%-20s | r = %6.4f | p-value = %.4f | %s\n",
              v, kor$estimate, kor$p.value,
              ifelse(kor$p.value < 0.05, "SIGNIFIKAN *", "tidak signifikan")))
}
## margin               | r = 0.9206 | p-value = 0.0000 | SIGNIFIKAN *
## sales                | r = 0.7973 | p-value = 0.0000 | SIGNIFIKAN *
## marketing            | r = 0.2255 | p-value = 0.0000 | SIGNIFIKAN *
## cogs                 | r = 0.4648 | p-value = 0.0000 | SIGNIFIKAN *
## total_expenses       | r = 0.2000 | p-value = 0.0000 | SIGNIFIKAN *

Interpretasi: margin memiliki korelasi tertinggi dengan profit. Ini merupakan insight terkuat dalam dataset. sales juga berkorelasi kuat. marketing memiliki korelasi yang signifikan secara statistik (p < 0.05, didorong oleh besarnya n = 4.248), namun hubungannya lemah secara praktis. Oleh karena itu, tidak tepat menyimpulkan bahwa marketing adalah penentu utama profit hanya karena p-value-nya kecil.


4.2 Uji Korelasi: Daya Beli (Income) vs Total Profit per State

Bagian ini secara langsung menjawab pertanyaan utama insight dengan uji statistik formal.

cat("=== Uji Korelasi Pearson: Daya Beli vs Total Profit per State ===\n\n")
## === Uji Korelasi Pearson: Daya Beli vs Total Profit per State ===
kor_income <- cor.test(data_gabung$median_mean_income,
                       data_gabung$total_profit,
                       method = "pearson")

cat(sprintf("Variabel          : median_mean_income vs total_profit\n"))
## Variabel          : median_mean_income vs total_profit
cat(sprintf("n (state)         : %d\n", nrow(data_gabung)))
## n (state)         : 20
cat(sprintf("Koefisien Korelasi: r = %.4f\n", kor_income$estimate))
## Koefisien Korelasi: r = 0.2323
cat(sprintf("p-value           : %.4f\n", kor_income$p.value))
## p-value           : 0.3244
cat(sprintf("95%% CI            : [%.4f, %.4f]\n",
            kor_income$conf.int[1], kor_income$conf.int[2]))
## 95% CI            : [-0.2343, 0.6119]
cat(sprintf("Kesimpulan        : %s\n",
            ifelse(kor_income$p.value < 0.05,
                   "SIGNIFIKAN * — terdapat hubungan linear antara income dan profit",
                   "Tidak signifikan — tidak cukup bukti adanya hubungan linear")))
## Kesimpulan        : Tidak signifikan — tidak cukup bukti adanya hubungan linear

Interpretasi: Uji korelasi Pearson antara median_mean_income dan total_profit di level state memberikan jawaban langsung atas pertanyaan utama laporan ini. Hasil menunjukkan korelasi positif namun tidak signifikan secara statistik (p > 0.05), artinya tidak cukup bukti bahwa negara bagian dengan income lebih tinggi secara konsisten menghasilkan profit lebih besar, pada level agregat state dengan n yang kecil. Perlu diperhatikan pula bahwa korelasi di level state ini juga dipengaruhi oleh jumlah transaksi per state. Analisis lebih lanjut di level transaksi dilakukan melalui model regresi.


4.3 Model 1: Regresi Linear Sederhana (profit ~ margin)

model_1 <- lm(profit ~ margin, data = coffee_model)
summary(model_1)
## 
## Call:
## lm(formula = profit ~ margin, data = coffee_model)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -295.859  -12.801    6.893   24.650  220.291 
## 
## Coefficients:
##               Estimate Std. Error t value Pr(>|t|)    
## (Intercept) -42.411601   0.908535  -46.68   <2e-16 ***
## margin        0.992483   0.006461  153.62   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 39.72 on 4246 degrees of freedom
## Multiple R-squared:  0.8475, Adjusted R-squared:  0.8475 
## F-statistic: 2.36e+04 on 1 and 4246 DF,  p-value: < 2.2e-16

Interpretasi: Model paling sederhana menggunakan margin sebagai satu-satunya prediktor. R² yang diperoleh menunjukkan bahwa margin tunggal sudah mampu menjelaskan sebagian besar variasi profit per transaksi. Koefisien margin positif dan sangat signifikan (p < 0.001). Ini menjadi baseline yang kuat, sekaligus mengkonfirmasi bahwa margin adalah penggerak utama profitabilitas Coffee Chain. Model ini belum memperhitungkan faktor biaya, pengeluaran lain, maupun konteks daya beli yang secara teoritis juga relevan.


4.4 Model 2: Regresi Linear Berganda dengan Skala Asli (profit ~ 6 prediktor, termasuk income)

Model 2 diperluas dengan menyertakan median_mean_income sebagai representasi daya beli masyarakat per negara bagian. Ini merupakan pengujian inferensial langsung atas pertanyaan utama insight.

model_2 <- lm(profit ~ margin + sales + marketing + cogs + total_expenses +
                median_mean_income,
              data = coffee_model)
summary(model_2)
## 
## Call:
## lm(formula = profit ~ margin + sales + marketing + cogs + total_expenses + 
##     median_mean_income, data = coffee_model)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -112.792   -5.661    0.024    5.431  112.825 
## 
## Coefficients:
##                      Estimate Std. Error t value Pr(>|t|)    
## (Intercept)         3.873e+00  1.892e+00   2.047   0.0407 *  
## margin             -4.119e-01  2.966e-02 -13.884  < 2e-16 ***
## sales               1.614e+00  2.945e-02  54.814  < 2e-16 ***
## marketing           2.618e-01  3.987e-02   6.565 5.84e-11 ***
## cogs               -1.659e+00  3.167e-02 -52.385  < 2e-16 ***
## total_expenses     -1.455e+00  3.074e-02 -47.347  < 2e-16 ***
## median_mean_income -1.119e-05  2.790e-05  -0.401   0.6884    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 16.49 on 4241 degrees of freedom
## Multiple R-squared:  0.9738, Adjusted R-squared:  0.9737 
## F-statistic: 2.622e+04 on 6 and 4241 DF,  p-value: < 2.2e-16

Interpretasi: Dengan menambahkan lima prediktor internal plus median_mean_income, R² meningkat signifikan dari Model 1. Pengaruh masing-masing prediktor:

  • margin → pada output tampak negatif, padahal korelasi bivariat margin–profit sangat kuat positif. Ini bukan kesalahan hitung, melainkan konsekuensi multikolinearitas: variabel margin, sales, cogs, dan total_expenses saling berkorelasi kuat karena secara akuntansi memang terkait dalam satu persamaan (profit = sales − cogs − expenses; margin ≈ sales − cogs). Ketika semua variabel ini masuk model secara bersamaan, koefisien parsial masing-masing mencerminkan marginal effect setelah variabel lain dikontrol, sehingga tanda bisa berubah. Interpretasi koefisien individual dalam kondisi multikolinearitas tinggi perlu dilakukan dengan hati-hati, sehingga fokus yang lebih tepat adalah pada signifikansi model secara keseluruhan (F-test dan R²) dan konsistensi tanda koefisien di Model 3.
  • sales → positif: volume penjualan lebih tinggi mendorong profit.
  • cogs → negatif: biaya pokok produksi menekan profit.
  • marketing → koefisiennya negatif setelah dikontrol variabel lain, hal ini juga mencerminkan efek multikolinearitas dengan total_expenses. Artinya marketing tidak bisa diinterpretasikan secara mandiri dari komponen pengeluaran lainnya.
  • total_expenses → negatif: beban total langsung mengurangi profit akhir.
  • median_mean_incometidak signifikan (p > 0.05) pada skala asli. Ini mengindikasikan bahwa setelah faktor operasional internal dikontrol, daya beli masyarakat tidak memberikan pengaruh tambahan yang terdeteksi secara statistik terhadap profit per transaksi. Analisis Model 3 akan memberikan gambaran yang lebih robust.

4.5 Model 3: Regresi Linear Berganda dengan Skala Log (log_profit ~ 6 prediktor, termasuk income)

model_3 <- lm(log_profit ~ margin + sales + marketing + cogs + total_expenses +
                median_mean_income,
              data = coffee_model)
summary(model_3)
## 
## Call:
## lm(formula = log_profit ~ margin + sales + marketing + cogs + 
##     total_expenses + median_mean_income, data = coffee_model)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -5.2498 -0.0097  0.0028  0.0158  0.2733 
## 
## Coefficients:
##                      Estimate Std. Error t value Pr(>|t|)    
## (Intercept)         6.502e+00  1.182e-02 550.227  < 2e-16 ***
## margin              1.087e-03  1.853e-04   5.868 4.74e-09 ***
## sales               1.213e-03  1.839e-04   6.595 4.77e-11 ***
## marketing           2.432e-04  2.490e-04   0.976   0.3289    
## cogs               -2.075e-03  1.978e-04 -10.491  < 2e-16 ***
## total_expenses     -2.214e-03  1.920e-04 -11.533  < 2e-16 ***
## median_mean_income -3.860e-07  1.743e-07  -2.215   0.0268 *  
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.103 on 4241 degrees of freedom
## Multiple R-squared:  0.7331, Adjusted R-squared:  0.7327 
## F-statistic:  1941 on 6 and 4241 DF,  p-value: < 2.2e-16

Interpretasi: Model 3 menggunakan spesifikasi berbeda secara fundamental dari Model 2: variabel respons ditransformasi ke skala log (log(profit_shifted)). Tujuannya adalah mengatasi skewness dan outlier pada data profit asli, sehingga asumsi OLS lebih terpenuhi. Temuan utama:

  • median_mean_income pada Model 3 kemungkinan menunjukkan signifikansi yang berbeda dari Model 2. Jika signifikan di sini namun tidak di Model 2, ini menunjukkan bahwa pengaruh income lemah dan sensitif terhadap distribusi data yang hanya terdeteksi setelah transformasi meredam distorsi outlier.
  • Efek praktis income sangat kecil: Koefisien median_mean_income pada skala log memiliki nilai yang sangat kecil. Menggunakan rumus semi-log: kenaikan income sebesar $10.000 menghasilkan perubahan profit_shifted sebesar (exp(β × 10000) - 1) × 100%, yang secara praktis hampir tidak berarti. Ini adalah contoh klasik di mana statistically significant ≠ practically important.
  • Catatan level analisis: Variabel median_mean_income berada pada level agregat (state), sementara variabel lain berada di level transaksi. Penggunaan variabel level-state dalam model level-transaksi dapat menimbulkan pseudo-replication, sehingga interpretasi koefisien income perlu dilakukan dengan kehati-hatian tambahan.

4.6 Pemeriksaan Asumsi Model 2 dan Model 3

par(mfrow = c(2, 2))
plot(model_2,
     sub.caption = "Diagnostik Asumsi: Model 2 — Regresi Berganda Skala Asli")

par(mfrow = c(1, 1))
par(mfrow = c(2, 2))
plot(model_3,
     sub.caption = "Diagnostik Asumsi: Model 3 — Regresi Berganda Skala Log")

par(mfrow = c(1, 1))

Interpretasi Perbandingan Diagnostik:

Asumsi Model 2 (Skala Asli) Model 3 (Skala Log)
Linieritas (Res. vs Fitted) Relatif terpenuhi, sedikit pola Lebih acak, pola berkurang
Normalitas residual (Q-Q) Deviasi di kedua ekor Lebih mendekati garis diagonal
Homoskedastisitas (Scale-Location) Garis tidak sepenuhnya datar Lebih mendatar, varians lebih stabil
Influential points (Cook’s distance) Beberapa titik leverage tinggi Lebih merata

Model 3 memenuhi asumsi regresi secara lebih baik dibanding Model 2, terutama pada aspek normalitas residual dan homoskedastisitas. Oleh karena itu, kesimpulan inferensial tentang pengaruh median_mean_income sebaiknya didasarkan pada hasil Model 3.


4.7 Perbandingan Ketiga Model

# RMSE Model 3 dihitung setelah back-transform ke skala profit asli
# agar perbandingan dengan Model 1 dan 2 adil
pred_log_m3   <- fitted(model_3)
profit_hat_m3 <- exp(pred_log_m3) + min_profit - 1
rmse_m3       <- sqrt(mean((coffee_model$profit - profit_hat_m3)^2))

hasil_perbandingan <- data.frame(
  Model = c(
    "Model 1: Sederhana — profit ~ margin",
    "Model 2: Berganda Skala Asli — profit ~ 6 prediktor (+ income)",
    "Model 3: Berganda Skala Log — log(profit_shifted) ~ 6 prediktor (+ income)"
  ),
  Pendekatan = c(
    "OLS, 1 prediktor",
    "OLS, 6 prediktor, skala asli",
    "OLS, 6 prediktor, transformasi log (robust)"
  ),
  N = rep(nrow(coffee_model), 3),
  R2 = c(
    round(summary(model_1)$r.squared, 4),
    round(summary(model_2)$r.squared, 4),
    round(summary(model_3)$r.squared, 4)
  ),
  Adj_R2 = c(
    round(summary(model_1)$adj.r.squared, 4),
    round(summary(model_2)$adj.r.squared, 4),
    round(summary(model_3)$adj.r.squared, 4)
  ),
  RMSE = c(
    round(sqrt(mean(model_1$residuals^2)), 2),
    round(sqrt(mean(model_2$residuals^2)), 2),
    round(rmse_m3, 2)
  )
)

knitr::kable(hasil_perbandingan,
             col.names = c("Model", "Pendekatan", "n", "R²", "Adj. R²",
                           "RMSE (skala profit asli)"),
             caption   = "Perbandingan Performa Ketiga Model Regresi",
             align     = c("l", "l", "r", "r", "r", "r"))
Perbandingan Performa Ketiga Model Regresi
Model Pendekatan n Adj. R² RMSE (skala profit asli)
Model 1: Sederhana — profit ~ margin OLS, 1 prediktor 4248 0.8475 0.8475 39.71
Model 2: Berganda Skala Asli — profit ~ 6 prediktor (+ income) OLS, 6 prediktor, skala asli 4248 0.9738 0.9737 16.48
Model 3: Berganda Skala Log — log(profit_shifted) ~ 6 prediktor (+ income) OLS, 6 prediktor, transformasi log (robust) 4248 0.7331 0.7327 51.26

Catatan: R² Model 3 dihitung dalam skala log sehingga tidak dapat dibandingkan langsung dengan R² Model 1 & 2. Untuk keadilan perbandingan, RMSE Model 3 dihitung setelah back-transforming prediksi ke skala profit asli.

Interpretasi:

  • Model 1 : paling sederhana dan interpretatif. Margin saja sudah menjelaskan sebagian besar variasi profit. Cocok untuk komunikasi kepada pemangku kepentingan non-teknis.
  • Model 2 : R² tertinggi dan RMSE terkecil dalam skala asli. Optimal untuk prediksi numerik profit. Menyertakan income sebagai prediktor sehingga pengaruh daya beli dapat dievaluasi langsung.
  • Model 3 : paling robust secara statistik: asumsi OLS lebih terpenuhi sehingga inferensi (termasuk tentang signifikansi income) lebih dapat diandalkan. RMSE back-transformed sedikit lebih besar, trade-off wajar untuk mendapatkan model yang lebih andal secara statistik.

Rekomendasi: Model 2 untuk prediksi numerik; Model 3 untuk inferensi dan pengambilan keputusan, khususnya dalam mengevaluasi apakah daya beli masyarakat benar-benar memengaruhi profit secara statistik.


4.8 Tabel Koefisien Model 2 dan Model 3

fmt_koef <- function(model, caption_text) {
  koef <- as.data.frame(summary(model)$coefficients)
  koef$Variabel <- rownames(koef)
  rownames(koef) <- NULL
  koef <- koef[, c("Variabel", "Estimate", "Std. Error", "t value", "Pr(>|t|)")]
  names(koef) <- c("Variabel", "Estimasi", "Std. Error", "t-value", "p-value")
  koef[, 2:5] <- round(koef[, 2:5], 6)
  knitr::kable(koef, caption = caption_text,
               align = c("l", "r", "r", "r", "r"))
}

fmt_koef(model_2,
  "Koefisien Model 2: profit ~ margin + sales + marketing + cogs + total_expenses + median_mean_income")
Koefisien Model 2: profit ~ margin + sales + marketing + cogs + total_expenses + median_mean_income
Variabel Estimasi Std. Error t-value p-value
(Intercept) 3.872845 1.892112 2.046837 0.040736
margin -0.411855 0.029664 -13.883905 0.000000
sales 1.614084 0.029447 54.813864 0.000000
marketing 0.261761 0.039873 6.564869 0.000000
cogs -1.658995 0.031669 -52.384992 0.000000
total_expenses -1.455488 0.030741 -47.347312 0.000000
median_mean_income -0.000011 0.000028 -0.401031 0.688417
fmt_koef(model_3,
  "Koefisien Model 3: log(profit_shifted) ~ margin + sales + marketing + cogs + total_expenses + median_mean_income")
Koefisien Model 3: log(profit_shifted) ~ margin + sales + marketing + cogs + total_expenses + median_mean_income
Variabel Estimasi Std. Error t-value p-value
(Intercept) 6.502328 0.011818 550.227044 0.000000
margin 0.001087 0.000185 5.868211 0.000000
sales 0.001213 0.000184 6.595043 0.000000
marketing 0.000243 0.000249 0.976403 0.328920
cogs -0.002075 0.000198 -10.491403 0.000000
total_expenses -0.002214 0.000192 -11.532543 0.000000
median_mean_income 0.000000 0.000000 -2.214825 0.026825

Interpretasi: Berdasarkan tabel koefisien di atas, temuan untuk median_mean_income:

  • Model 2 (skala asli): koefisien tidak signifikan (p > 0.05), temuan ini menunjukkan bahwa daya beli masyarakat tidak berpengaruh signifikan secara statistik setelah faktor operasional dikontrol pada skala profit asli.
  • Model 3 (skala log): meski kemungkinan lebih kecil, besarnya koefisien sangat kecil sehingga pengaruhnya tidak signifikan secara praktis. Kenaikan income ribuan dolar hanya mengubah profit dalam persentase yang sangat kecil.

Inkonsistensi (atau kelemahan) signifikansi income antara kedua model mengindikasikan bahwa pengaruhnya lemah dan tidak stabil. Ini memperkuat kesimpulan bahwa daya beli masyarakat bukan penentu utama profitabilitas Coffee Chain.

Untuk variabel internal: tanda koefisien pada sales (positif) dan cogs, total_expenses (negatif) konsisten antara kedua model, hal ini memperkuat validitas temuan bahwa faktor operasional internal adalah penggerak dominan profit. Perubahan tanda margin di Model 2 merupakan artefak multikolinearitas, sebagaimana telah dibahas di Bagian 4.4.

Catatan penting: Seluruh hubungan yang ditemukan dalam analisis ini bersifat asosiatif, bukan kausal. Korelasi dan regresi tidak membuktikan bahwa income menyebabkan perubahan profit. Faktor lain yang tidak terukur (confounding variables) mungkin menjelaskan hubungan yang teramati.


5. Kesimpulan

Berdasarkan seluruh analisis terhadap Coffee Chain Dataset yang diperkaya dengan US Household Income Dataset, diperoleh lima kesimpulan utama:

  1. Produk Colombian adalah yang paling menguntungkan, sementara Green Tea satu-satunya produk dengan profit negatif. Green Tea perlu dievaluasi menyeluruh dari sisi harga jual, biaya produksi, dan permintaan pasar.

  2. California dan Illinois adalah negara bagian dengan profit tertinggi. Wilayah South secara konsisten memiliki performa paling rendah, dengan New Mexico sebagai yang terendah.

  3. Margin adalah faktor internal terkuat penentu profit (r sangat kuat, mendekati 1). Marketing berpengaruh signifikan secara statistik namun lemah secara praktis. Menunjukkan bahwa pengeluaran marketing tidak serta-merta mendorong profit tanpa didukung efisiensi margin. Strategi yang berfokus pada peningkatan efisiensi margin terbukti lebih efektif secara kuantitatif.

  4. Daya beli masyarakat bukan penentu utama profitabilitas (jawaban atas insight utama): Berdasarkan uji korelasi di level state (tidak signifikan, p > 0.05) dan model regresi berganda, median_mean_income tidak signifikan di Model 2 dan hanya signifikan secara marginal di Model 3 dengan efek praktis yang sangat kecil. Hal ini menunjukkan bahwa pengaruh income lemah, tidak konsisten antar model, dan tidak signifikan secara praktis. Dibandingkan dengan faktor internal seperti margin dan volume penjualan, peran income jauh kurang dominan.Perbedaan profit antar negara bagian lebih banyak dijelaskan oleh volume transaksi dan komposisi produk, bukan oleh tingkat pendapatan rumah tangga di wilayah tersebut. Perlu dicatat pula bahwa hubungan yang ditemukan bersifat asosiatif, bukan kausal.

  5. Ketiga model regresi memiliki peran berbeda yang saling melengkapi. Model 1 (sederhana) memberikan baseline yang kuat dan mudah dikomunikasikan. Model 2 (berganda skala asli) memberikan prediksi numerik terbaik sekaligus menguji pengaruh income secara langsung. Model 3 (berganda skala log) menghasilkan asumsi OLS yang lebih terpenuhi. Oleh karena itu, kesimpulan inferensial tentang pengaruh daya beli sebaiknya didasarkan pada Model 3 karena lebih robust terhadap outlier dan skewness data profit.