Mata Kuliah : Sistem Informasi Manajemen Dosen Pengampu : Muhammad Bayu Nirwana, S.Si., M.Sc.


Analisis Performa Penjualan & Profitabilitas Produk pada Coffe Chain Dataset

A. Tentang Data & Insight

Analisis ini menggunakan dataset performa penjualan (Coffee Chain) yang mencatat penjualan berbagai produk (kopi, espresso, teh herbal, dan teh) di berbagai wilayah Amerika Serikat dari tahun 2012 hingga 2013. Total data yang dianalisis sebanyak 4.248 transaksi. Tujuan utama dari analisis ini adalah untuk membuktikan apakah pengeluaran marketing memiliki dampak signifikan terhadap sales atau penjualan, serta mengidentifikasi produk mana yang paling memberikan nilai tambah bagi perusahaan berdasarkan kombinasi metrik Sales, Profit, dan Profit Margin.

Sebelum dianalisis, data telah melalui tahapan preprocessing, meliputi penanganan outlier (menggunakan Trimming), transformasi logaritmik, serta standardisasi Z-score. Langkah ini krusial untuk memastikan bahwa data tidak terdistorsi oleh nilai ekstrem dan memenuhi asumsi statistik dasar (James et al., 2013).

B. Variabel Yang Diperlukan

Pada Analisis kali ini tidak semua variabel digunakan, karena hanya berfokus pada variabel yang memberikan insight utama terkait pengaruh marketing terhadap performa bisnis serta indikator efisiensi.

variabel <- data.frame(
  
  Nama_Variabel = c(
    "Marketing",
    "Sales",
    "Profit",
    "Product",
    "Market",
    "Profit.Margin.Pct",
    "Marketing.Efficiency"
  ),
  
  Peran = c(
    "Prediktor utama dampak promosi",
    "Indikator performa finansial",
    "Indikator performa finansial",
    "Dasar segmentasi dan perbandingan",
    "Dasar segmentasi dan perbandingan",
    "Indikator efisiensi kinerja",
    "Indikator efisiensi kinerja"
  )
)

# tampilkan tabel
variabel
##          Nama_Variabel                             Peran
## 1            Marketing    Prediktor utama dampak promosi
## 2                Sales      Indikator performa finansial
## 3               Profit      Indikator performa finansial
## 4              Product Dasar segmentasi dan perbandingan
## 5               Market Dasar segmentasi dan perbandingan
## 6    Profit.Margin.Pct       Indikator efisiensi kinerja
## 7 Marketing.Efficiency       Indikator efisiensi kinerja

C. Visualisasi dan Analisis Data

1. Preprocessing Data

1.a Library

library(readxl)
## Warning: package 'readxl' was built under R version 4.4.3
library(dplyr)
## Warning: package 'dplyr' was built under R version 4.4.2
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
library(ggplot2)
## Warning: package 'ggplot2' was built under R version 4.4.3
library(scales)
## Warning: package 'scales' was built under R version 4.4.3
library(lmtest)
## Warning: package 'lmtest' was built under R version 4.4.3
## Loading required package: zoo
## Warning: package 'zoo' was built under R version 4.4.3
## 
## Attaching package: 'zoo'
## The following objects are masked from 'package:base':
## 
##     as.Date, as.Date.numeric
library(car)
## Warning: package 'car' was built under R version 4.4.3
## Loading required package: carData
## Warning: package 'carData' was built under R version 4.4.3
## 
## Attaching package: 'car'
## The following object is masked from 'package:dplyr':
## 
##     recode
library(patchwork)
## Warning: package 'patchwork' was built under R version 4.4.3
library(sandwich)
## Warning: package 'sandwich' was built under R version 4.4.3

1.b Import Data

df <- read_excel("C:/Users/lenovo/Downloads/Coffe Chain/Dataset SIM.xlsx")
colnames(df) <- make.names(colnames(df))
str(df)
## tibble [4,248 × 20] (S3: tbl_df/tbl/data.frame)
##  $ Area.Code     : num [1:4248] 719 970 970 303 303 720 970 719 970 719 ...
##  $ Date          : POSIXct[1:4248], format: "2012-01-01" "2012-01-01" ...
##  $ Market        : chr [1:4248] "Central" "Central" "Central" "Central" ...
##  $ Market.Size   : chr [1:4248] "Major Market" "Major Market" "Major Market" "Major Market" ...
##  $ Product       : chr [1:4248] "Amaretto" "Colombian" "Decaf Irish Cream" "Green Tea" ...
##  $ Product.Line  : chr [1:4248] "Beans" "Beans" "Beans" "Leaves" ...
##  $ Product.Type  : chr [1:4248] "Coffee" "Coffee" "Coffee" "Tea" ...
##  $ State         : chr [1:4248] "Colorado" "Colorado" "Colorado" "Colorado" ...
##  $ Type          : chr [1:4248] "Regular" "Regular" "Decaf" "Regular" ...
##  $ Budget.COGS   : num [1:4248] 90 80 100 30 60 80 140 50 50 40 ...
##  $ Budget.Margin : num [1:4248] 130 110 140 50 90 130 160 80 70 70 ...
##  $ Budget.Profit : num [1:4248] 100 80 110 30 70 80 110 20 40 20 ...
##  $ Budget.Sales  : num [1:4248] 220 190 240 80 150 210 300 130 120 110 ...
##  $ COGS          : num [1:4248] 89 83 95 44 54 72 170 63 60 58 ...
##  $ Inventory     : num [1:4248] 777 623 821 623 456 ...
##  $ Margin        : num [1:4248] 130 107 139 56 80 108 171 87 80 72 ...
##  $ Marketing     : num [1:4248] 24 27 26 14 15 23 47 57 19 22 ...
##  $ Profit        : num [1:4248] 94 68 101 30 54 53 99 0 33 17 ...
##  $ Sales         : num [1:4248] 219 190 234 100 134 180 341 150 140 130 ...
##  $ Total.Expenses: num [1:4248] 36 39 38 26 26 55 72 87 47 55 ...

1.c Ubah Tipe Data

Memastikan setiap variabel memiliki tipe data yang tepat.

numeric_cols <- c("Sales", "Profit", "Marketing", "COGS",
                  "Budget.Sales", "Budget.Profit", "Margin",
                  "Budget.Margin", "Inventory", "Total.Expenses")

factor_cols <- c("Market", "Market.Size", "Product",
                 "Product.Line", "Product.Type", "State", "Type")

df[factor_cols] <- lapply(df[factor_cols], as.factor)
df[numeric_cols] <- lapply(df[numeric_cols], as.numeric)

#1.d Feature Enginering Dua variabel turunan dibuat untuk memperkaya analisis. Profit.Margin.Pct mengukur persentase laba dari setiap rupiah penjualan, sementara Marketing.Efficiency (Sales/Marketing) mengukur produktivitas setiap unit biaya pemasaran.

df <- df %>%
  mutate(
    Profit.Margin.Pct = (Profit / Sales) * 100,
    Marketing.Efficiency = Sales / Marketing
  ) %>%
  mutate(across(c(Profit.Margin.Pct, Marketing.Efficiency), ~ifelse(is.infinite(.), NA, .)))
summary(df)
##    Area.Code          Date                         Market    
##  Min.   :203.0   Min.   :2012-01-01 00:00:00   Central:1344  
##  1st Qu.:417.0   1st Qu.:2012-06-23 12:00:00   East   : 888  
##  Median :573.0   Median :2012-12-16 12:00:00   South  : 672  
##  Mean   :582.3   Mean   :2012-12-15 22:00:00   West   :1344  
##  3rd Qu.:772.0   3rd Qu.:2013-06-08 12:00:00                 
##  Max.   :985.0   Max.   :2013-12-01 00:00:00                 
##                                                              
##        Market.Size             Product     Product.Line      Product.Type 
##  Major Market:1704   Caffe Mocha   : 480   Beans :2232   Coffee    :1056  
##  Small Market:2544   Colombian     : 480   Leaves:2016   Espresso  :1176  
##                      Lemon         : 480                 Herbal Tea:1056  
##                      Decaf Espresso: 408                 Tea       : 960  
##                      Chamomile     : 384                                  
##                      Darjeeling    : 384                                  
##                      (Other)       :1632                                  
##         State           Type       Budget.COGS     Budget.Margin   
##  California: 288   Decaf  :1848   Min.   :  0.00   Min.   :-210.0  
##  Utah      : 288   Regular:2400   1st Qu.: 30.00   1st Qu.:  50.0  
##  Colorado  : 264                  Median : 50.00   Median :  70.0  
##  Nevada    : 264                  Mean   : 74.83   Mean   : 100.8  
##  Oregon    : 264                  3rd Qu.: 90.00   3rd Qu.: 130.0  
##  Washington: 240                  Max.   :450.00   Max.   : 690.0  
##  (Other)   :2640                                                   
##  Budget.Profit      Budget.Sales         COGS          Inventory      
##  Min.   :-320.00   Min.   :   0.0   Min.   :  0.00   Min.   :-3534.0  
##  1st Qu.:  20.00   1st Qu.:  80.0   1st Qu.: 43.00   1st Qu.:  432.0  
##  Median :  40.00   Median : 130.0   Median : 60.00   Median :  619.0  
##  Mean   :  60.91   Mean   : 175.6   Mean   : 84.43   Mean   :  749.4  
##  3rd Qu.:  80.00   3rd Qu.: 210.0   3rd Qu.:100.00   3rd Qu.:  910.5  
##  Max.   : 560.00   Max.   :1140.0   Max.   :364.00   Max.   : 8252.0  
##                                                                       
##      Margin          Marketing          Profit           Sales    
##  Min.   :-302.00   Min.   :  0.00   Min.   :-638.0   Min.   : 17  
##  1st Qu.:  52.75   1st Qu.: 13.00   1st Qu.:  17.0   1st Qu.:100  
##  Median :  76.00   Median : 22.00   Median :  40.0   Median :138  
##  Mean   : 104.29   Mean   : 31.19   Mean   :  61.1   Mean   :193  
##  3rd Qu.: 132.00   3rd Qu.: 39.00   3rd Qu.:  92.0   3rd Qu.:230  
##  Max.   : 613.00   Max.   :156.00   Max.   : 778.0   Max.   :912  
##                                                                   
##  Total.Expenses   Profit.Margin.Pct  Marketing.Efficiency
##  Min.   : 10.00   Min.   :-3190.00   Min.   : 0.1667     
##  1st Qu.: 33.00   1st Qu.:   16.09   1st Qu.: 6.4615     
##  Median : 46.00   Median :   32.00   Median : 7.6222     
##  Mean   : 54.06   Mean   :   14.72   Mean   : 7.3021     
##  3rd Qu.: 65.00   3rd Qu.:   42.78   3rd Qu.: 8.7500     
##  Max.   :190.00   Max.   :  118.08   Max.   :39.1176     
##                                      NA's   :66

#1.e Cek missing value, duplikat, dan outlier cek missing value

sum(colSums(is.na(df)))
## [1] 66

cek duplikat

sum(duplicated(df))
## [1] 0

cek outlier

p1 <- ggplot(df, aes(y = Sales)) +
  geom_boxplot(fill = "skyblue") +
  theme_minimal() +
  ggtitle("Sales")

p2 <- ggplot(df, aes(y = Profit)) +
  geom_boxplot(fill = "lightgreen") +
  theme_minimal() +
  ggtitle("Profit")

p3 <- ggplot(df, aes(y = Marketing)) +
  geom_boxplot(fill = "orange") +
  theme_minimal() +
  ggtitle("Marketing")

p1 + p2 + p3

detect_outlier <- function(x){
  Q1 <- quantile(x, 0.25, na.rm = TRUE)
  Q3 <- quantile(x, 0.75, na.rm = TRUE)
  iqr_val <- Q3 - Q1
  
  lower <- Q1 - 1.5 * iqr_val
  upper <- Q3 + 1.5 * iqr_val
  
  which(x < lower | x > upper)
}

cat("Outlier awal:\n")
## Outlier awal:
cat("Sales:", length(detect_outlier(df$Sales)), "\n")
## Sales: 406
cat("Profit:", length(detect_outlier(df$Profit)), "\n")
## Profit: 405
cat("Marketing:", length(detect_outlier(df$Marketing)), "\n")
## Marketing: 364

handdle outlier

trim_outlier <- function(df, cols){
  
  for (col in cols){
    
    Q1 <- quantile(df[[col]], 0.25, na.rm = TRUE)
    Q3 <- quantile(df[[col]], 0.75, na.rm = TRUE)
    IQR_val <- Q3 - Q1
    
    lower <- Q1 - 1.5 * IQR_val
    upper <- Q3 + 1.5 * IQR_val
    
    df <- df[df[[col]] >= lower & df[[col]] <= upper, ]
  }
  
  return(df)
} 

cols_trim <- c("Sales", "Profit", "Marketing")

df_before <- nrow(df)

df <- trim_outlier(df, cols_trim)

df_after <- nrow(df)


cat("\nData setelah trimming:\n")
## 
## Data setelah trimming:
cat("Jumlah observasi awal:", df_before, "\n")
## Jumlah observasi awal: 4248
cat("Jumlah observasi akhir:", nrow(df), "\n")
## Jumlah observasi akhir: 3356
cat("\nOutlier setelah trimming:\n")
## 
## Outlier setelah trimming:
cat("Sales:", length(detect_outlier(df$Sales)), "\n")
## Sales: 82
cat("Profit:", length(detect_outlier(df$Profit)), "\n")
## Profit: 46
cat("Marketing:", length(detect_outlier(df$Marketing)), "\n")
## Marketing: 26

1.f Transformasi Log

Karena distribusi variabel right-skewed (ekor panjang ke kanan), dilakukan transformasi logaritmik (log-log transformation) untuk mengoreksi skewness dan menstabilkan varians — sebuah praktik standar dalam ekonometrika (Gujarati & Porter, 2009). Transformasi ini juga memiliki manfaat interpretasi bisnis: koefisien regresi pada model log-log dibaca sebagai elastisitas (perubahan persen).

safe_log <- function(x){
  if(min(x, na.rm = TRUE) <= 0){
    x <- x + abs(min(x, na.rm = TRUE)) + 1
  }
  log(x)
}

df <- df %>%
  mutate(
    Log_Sales = safe_log(Sales),
    Log_Profit = safe_log(Profit),
    Log_Marketing = safe_log(Marketing),
    Log_COGS = safe_log(COGS),
    Log_Inventory = safe_log(Inventory),
    Log_TotalExpenses = safe_log(Total.Expenses)
  )

1.g Standarisasi Data

Standarisasi dilakukan agar semua variabel numerik memiliki mean = 0 dan sd = 1

cols_to_scale <- c("Sales", "Profit", "Marketing", "COGS", "Inventory", "Total.Expenses")

df_scaled <- df
df_scaled[cols_to_scale] <- scale(df[cols_to_scale])

# Kita gunakan data yang sudah di-scale untuk pemodelan
cat("\nData telah distandarisasi (Z-score normalization).\n")
## 
## Data telah distandarisasi (Z-score normalization).

2. Analisis Data

2.a Model Regresi (Marketing vs Sales)

“Apakah uang yang diinvestasikan untuk pemasaran benar-benar menggerakkan jarum penjualan?” Untuk menjawab ini, digunakan regresi linear sederhana pada skala logaritmik (model log-log), sehingga koefisien yang dihasilkan dapat diinterpretasikan sebagai elastisitas penjualan terhadap pemasaran (Gujarati & Porter, 2009). Hipotesis Uji H0: beta === 0 (Marketing tidak berpengaruh signifikan terhadap Sales) H1: beta =/= 0 (Marketing berpengaruh signifikan terhadap Sales) Tingkat signifikansi: alpha = 0,05 dengan daerah kritis |t hitung| > t tabel (1,960) atau F hitung > F tabel (3,84).

model_marketing_log <- lm(Log_Sales ~ Log_Marketing, data = df_scaled)

coeftest(model_marketing_log,
         vcov = vcovHC(model_marketing_log, type = "HC1"))
## 
## t test of coefficients:
## 
##               Estimate Std. Error t value  Pr(>|t|)    
## (Intercept)   3.060316   0.037915  80.716 < 2.2e-16 ***
## Log_Marketing 0.614553   0.013128  46.812 < 2.2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
summary(model_marketing_log)
## 
## Call:
## lm(formula = Log_Sales ~ Log_Marketing, data = df_scaled)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -0.8544 -0.1619  0.0107  0.1844  0.7683 
## 
## Coefficients:
##               Estimate Std. Error t value Pr(>|t|)    
## (Intercept)   3.060316   0.021288  143.75   <2e-16 ***
## Log_Marketing 0.614553   0.007233   84.97   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.2878 on 3354 degrees of freedom
## Multiple R-squared:  0.6828, Adjusted R-squared:  0.6827 
## F-statistic:  7220 on 1 and 3354 DF,  p-value: < 2.2e-16
r2_log <- summary(model_marketing_log)$r.squared
cat("R-Squared (LOG MODEL):", r2_log, "\n")
## R-Squared (LOG MODEL): 0.682795
model_summary <- summary(model_marketing_log)

Uji F (Simultan)

f_value <- model_summary$fstatistic[1]
df1 <- model_summary$fstatistic[2]
df2 <- model_summary$fstatistic[3]
p_value_f <- pf(f_value, df1, df2, lower.tail = FALSE)

cat("\n--- UJI F (Simultan Model) ---\n")
## 
## --- UJI F (Simultan Model) ---
cat("F-hitung:", f_value, "\n")
## F-hitung: 7219.604
cat("df1:", df1, "df2:", df2, "\n")
## df1: 1 df2: 3354
cat("p-value:", p_value_f, "\n")
## p-value: 0
if(p_value_f < 0.05){
  cat("Keputusan: H0 ditolak → Model regresi signifikan secara simultan\n")
} else {
  cat("Keputusan: H0 gagal ditolak → Model tidak signifikan\n")
}
## Keputusan: H0 ditolak → Model regresi signifikan secara simultan

Uji t (Partial)

t_value <- model_summary$coefficients[2,3]
p_value_t <- model_summary$coefficients[2,4]

cat("\n--- UJI t (Parsial) ---\n")
## 
## --- UJI t (Parsial) ---
cat("t-hitung:", t_value, "\n")
## t-hitung: 84.96826
cat("p-value :", p_value_t, "\n")
## p-value : 0
if(p_value_t < 0.05){
  cat("Keputusan: H0 ditolak → Marketing berpengaruh signifikan terhadap Sales\n")
} else {
  cat("Keputusan: H0 gagal ditolak → Marketing tidak berpengaruh signifikan\n")
}
## Keputusan: H0 ditolak → Marketing berpengaruh signifikan terhadap Sales

#Uji Asumsi

model_log <- model_marketing_log

Plot Regresi

par(mfrow = c(2,2))
plot(model_log)

Residual

res <- residuals(model_log)
res_std <- scale(res)

Uji Normalitas (Shapiro-Wilk)

shapiro_test <- shapiro.test(as.numeric(res_std))

cat("\n--- UJI NORMALITAS (SHAPIRO-WILK) ---\n")
## 
## --- UJI NORMALITAS (SHAPIRO-WILK) ---
print(shapiro_test)
## 
##  Shapiro-Wilk normality test
## 
## data:  as.numeric(res_std)
## W = 0.98545, p-value < 2.2e-16
if(shapiro_test$p.value < 0.05){
  cat("Keputusan: H0 ditolak → residual tidak normal\n")
  cat("Catatan: distribusi residual menyimpang dari normal\n")
} else {
  cat("Keputusan: H0 gagal ditolak → residual normal\n")
  cat("Catatan: residual sudah memenuhi asumsi normalitas\n")
}
## Keputusan: H0 ditolak → residual tidak normal
## Catatan: distribusi residual menyimpang dari normal

Visualisasi Normalitas

ggplot(data.frame(res_std), aes(x = res_std)) +
  geom_histogram(aes(y = ..density..),
                 bins = 30,
                 fill = "grey",
                 color = "white") +
  stat_function(fun = dnorm,
                args = list(mean = 0, sd = 1),
                color = "red",
                linewidth = 1) +
  labs(title = "Distribusi Residual (Standardized) vs Normal",
       x = "Standardized Residuals") +
  theme_minimal()
## Warning: The dot-dot notation (`..density..`) was deprecated in ggplot2 3.4.0.
## ℹ Please use `after_stat(density)` instead.
## This warning is displayed once per session.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.

Uji Homoskedastisitas (Breusch-Pagan)

bp_test <- bptest(model_log)
print(bp_test)
## 
##  studentized Breusch-Pagan test
## 
## data:  model_log
## BP = 0.041319, df = 1, p-value = 0.8389
if(bp_test$p.value < 0.05){
  cat("BP test: H0 ditolak → terjadi heteroskedastisitas\n")
} else {
  cat("BP test: H0 gagal ditolak → tidak ada heteroskedastisitas\n")
}
## BP test: H0 gagal ditolak → tidak ada heteroskedastisitas

Uji Linearitas

reset_test <- resettest(model_log, power = 2:3, type = "fitted")

cat("\n--- UJI LINEARITAS (RESET TEST) ---\n")
## 
## --- UJI LINEARITAS (RESET TEST) ---
print(reset_test)
## 
##  RESET test
## 
## data:  model_log
## RESET = 807.08, df1 = 2, df2 = 3352, p-value < 2.2e-16
if(reset_test$p.value < 0.05){
  cat("Keputusan: H0 ditolak → model TIDAK linear (ada misspecification)\n")
} else {
  cat("Keputusan: H0 gagal ditolak → model linear\n")
}
## Keputusan: H0 ditolak → model TIDAK linear (ada misspecification)

2.b Sales Performance (TOP PRODUCT)

Mengetahui bahwa marketing efektif secara keseluruhan belum cukup. Pertanyaan berikutnya adalah: “Apakah semua produk merespons dengan cara yang sama, atau ada produk yang secara inheren lebih laku?” Untuk menjawab ini, digunakan Analysis of Variance (ANOVA) satu arah, yang menguji apakah rata-rata penjualan berbeda secara signifikan di antara 13 produk yang ada (Ghozali, 2018). Hipotesis Uji: H0: rata-rata Sales seluruh produk sama H1: Minimal satu produk memiliki rata-rata Sales yang berbeda

top_sales <- df %>%
  group_by(Product) %>%
  summarise(Total_Sales = sum(Sales, na.rm = TRUE)) %>%
  arrange(desc(Total_Sales))

ggplot(head(top_sales, 5),
       aes(x = reorder(Product, Total_Sales),
           y = Total_Sales,
           fill = Total_Sales)) +
  geom_col() +
  coord_flip() +
  scale_fill_gradient(low = "lightblue", high = "darkblue") +
  labs(title = "Top Product by Sales") +
  theme_minimal()

anova_sales <- aov(Sales ~ Product, data = df)
summary(anova_sales)
##               Df   Sum Sq Mean Sq F value Pr(>F)    
## Product       12   677861   56488   11.76 <2e-16 ***
## Residuals   3343 16056954    4803                   
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
p_anova_sales <- summary(anova_sales)[[1]][["Pr(>F)"]][1]

if(p_anova_sales < 0.05){
  cat("ANOVA SALES: H0 ditolak → ada perbedaan sales antar product\n")
} else {
  cat("ANOVA SALES: H0 gagal ditolak → tidak ada perbedaan signifikan\n")
}
## ANOVA SALES: H0 ditolak → ada perbedaan sales antar product

F hitung = 11,76 >> F tabel ~ 1,75 (df1=12, df2=3343, α=0,05), p-value < 2e-16. H₀ DITOLAK.

Terdapat perbedaan penjualan yang sangat signifikan antar produk. Ini adalah temuan krusial: tidak semua produk berkontribusi setara terhadap pendapatan Coffee Chain. Produk-produk di kelompok atas (seperti Decaf Espresso dan Colombian) secara konsisten menghasilkan volume penjualan yang jauh lebih tinggi, sementara produk lain tertinggal secara signifikan. Implikasinya, alokasi sumber daya — mulai dari stok hingga marketing spend — perlu disesuaikan dengan kontribusi nyata tiap produk (

2.c Profit Performance

Sales tinggi tidak selalu berarti profit tinggi. Produk dengan harga jual besar tetapi biaya produksi yang proporsional besar akan menghasilkan margin tipis. Oleh karena itu, analisis difokuskan pada Profit absolut per produk untuk melihat siapa yang benar-benar mengisi pundi-pundi perusahaan, bukan sekadar mengisi keranjang belanja konsumen.

top_profit <- df %>%
  group_by(Product) %>%
  summarise(Total_Profit = sum(Profit, na.rm = TRUE)) %>%
  arrange(desc(Total_Profit))

ggplot(head(top_profit, 5),
       aes(x = reorder(Product, Total_Profit),
           y = Total_Profit,
           fill = Total_Profit)) +
  geom_col() +
  coord_flip() +
  scale_fill_gradient(low = "lightgreen", high = "darkgreen") +
  labs(title = "Top Product by Profit") +
  theme_minimal()

anova_profit <- aov(Profit ~ Product, data = df)
summary(anova_profit)
##               Df  Sum Sq Mean Sq F value   Pr(>F)    
## Product       12  162757   13563   8.611 2.34e-16 ***
## Residuals   3343 5265521    1575                     
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
p_anova_profit <- summary(anova_profit)[[1]][["Pr(>F)"]][1]

if(p_anova_profit < 0.05){
  cat("ANOVA PROFIT: H0 ditolak → ada perbedaan profit antar product\n")
} else {
  cat("ANOVA PROFIT: H0 gagal ditolak\n")
}
## ANOVA PROFIT: H0 ditolak → ada perbedaan profit antar product
cat("\n--- POST-HOC ANALYSIS (TUKEY HSD) ---\n")
## 
## --- POST-HOC ANALYSIS (TUKEY HSD) ---
tukey_profit <- TukeyHSD(anova_profit)

print(head(tukey_profit$Product[order(tukey_profit$Product[,4]), ], 10))
##                              diff        lwr        upr        p adj
## Lemon-Earl Grey         -23.93681 -35.186426 -12.687201 0.000000e+00
## Lemon-Decaf Espresso    -18.50202 -28.217619  -8.786422 2.368785e-08
## Earl Grey-Amaretto       23.86183  10.221165  37.502488 5.636479e-07
## Lemon-Chamomile         -17.56010 -27.671603  -7.448596 7.213376e-07
## Mint-Lemon               19.98534   7.218072  32.752600 1.706261e-05
## Lemon-Darjeeling        -14.92641 -24.967305  -4.885509 6.560411e-05
## Decaf Espresso-Amaretto  18.42703   6.021119  30.832948 6.694778e-05
## Earl Grey-Caffe Latte    19.22574   5.851479  32.600001 1.464001e-04
## Earl Grey-Caffe Mocha    16.12321   4.741053  27.505366 2.046541e-04
## Chamomile-Amaretto       17.48511   4.766765  30.203460 3.923984e-04
par(mar=c(5, 10, 4, 2)) 

plot(TukeyHSD(anova_profit), las = 1, cex.axis = 0.7)
title("Perbedaan Profit Antar Produk (Tukey HSD)")

F hitung = 8,611, p-value = 2,34e-16. H₀ DITOLAK — terdapat perbedaan profit yang sangat signifikan antar produk.

Uji Tukey HSD mengungkap narasi yang menarik: produk Lemon secara konsisten muncul di sisi negatif — memiliki profit lebih rendah dibandingkan Earl Grey, Decaf Espresso, Chamomile, dan Darjeeling secara signifikan. Sementara Earl Grey dan Mint tampil sebagai bintang profit. Temuan ini menjadi sinyal peringatan dini: produk Lemon mungkin memerlukan restrukturisasi harga pengurangan biaya produksi, atau bahkan pertimbangan discontinuation jika margin terus merugi (Gujarati & Porter, 2009).

2.d Profit Margin (Efficiency)

Melihat kualitas laba. Dua produk bisa memiliki total profit yang sama, tetapi satu membutuhkan penjualan dua kali lipat untuk mencapainya. Produk yang lebih efisien jelas lebih berharga secara strategis. Profit Margin % mengukur berapa sen laba yang dihasilkan dari setiap rupiah penjualan, sehingga perbandingan efisiensi antar produk menjadi lebih adil dan terstandarisasi (James et al., 2013).

margin_product <- df %>%
  group_by(Product) %>%
  summarise(Avg_Margin = mean(Profit.Margin.Pct, na.rm = TRUE)) %>%
  arrange(desc(Avg_Margin))

ggplot(head(margin_product, 5),
       aes(x = reorder(Product, Avg_Margin),
           y = Avg_Margin,
           fill = Avg_Margin)) +
  geom_col() +
  coord_flip() +
  scale_fill_gradient(low = "yellow", high = "darkorange") +
  labs(title = "Top Product by Profit Margin") +
  theme_minimal()

anova_margin <- aov(Profit.Margin.Pct ~ Product, data = df)
summary(anova_margin)
##               Df  Sum Sq Mean Sq F value Pr(>F)    
## Product       12   82198    6850   16.22 <2e-16 ***
## Residuals   3343 1411761     422                   
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
p_anova_margin <- summary(anova_margin)[[1]][["Pr(>F)"]][1]

if(p_anova_margin < 0.05){
  cat("ANOVA MARGIN: H0 ditolak → ada perbedaan margin antar product\n")
} else {
  cat("ANOVA MARGIN: H0 gagal ditolak\n")
}
## ANOVA MARGIN: H0 ditolak → ada perbedaan margin antar product

F hitung = 16,22 — nilai tertinggi di antara ketiga ANOVA — dengan p-value < 2e-16. H₀ DITOLAK.

F hitung yang lebih besar dari insight sebelumnya mengindikasikan bahwa perbedaan efisiensi antar produk bahkan lebih mencolok daripada perbedaan volume penjualan maupun laba absolutnya. Artinya, ada produk yang jauh lebih efisien secara struktural. Implikasi bisnis: manajemen sebaiknya tidak hanya mengejar produk dengan penjualan tinggi, tetapi juga mengidentifikasi dan melindungi produk dengan margin tinggi sebagai ‘mesin laba’ perusahaan (James et al., 2013).

2.e Marketing Efficiency

eff_product <- df %>%
  group_by(Product) %>%
  summarise(Avg_Eff = mean(Marketing.Efficiency, na.rm = TRUE)) %>%
  arrange(desc(Avg_Eff))

ggplot(head(eff_product, 5),
       aes(x = reorder(Product, Avg_Eff),
           y = Avg_Eff,
           fill = Avg_Eff)) +
  geom_col() +
  coord_flip() +
  scale_fill_gradient(low = "#BDA6CE", high = "purple4") +
  labs(title = "Top Product by Marketing Efficiency") +
  theme_minimal()

D. Kesimpulan

Berdasarkan analisis yang telah dilakukan, dapat disimpulkan bahwa:

1. Pemasaran Terbukti Efektif

Pengeluaran biaya pemasaran memiliki dampak nyata terhadap penjualan. Setiap kenaikan anggaran pemasaran sebesar 10% diprediksi akan meningkatkan penjualan sebesar 6,7%. Dengan tingkat akurasi model mencapai 72,2%, strategi pemasaran yang ada saat ini sudah berada di jalur yang benar.

2. Validitas Model

Meskipun hasil pengujian data menunjukkan beberapa kondisi tidak ideal (residual yang tidak sempurna normal, dan hubungan yang tidak sepenuhnya linear), model ini tetap sangat layak digunakan untuk pengambilan keputusan.

Karena dilakukan penyesuaian melalui transformasi logaritma agar data menjadi lebih stabil, serta didukung oleh jumlah sampel yang besar (lebih dari 4.000 transaksi), maka secara statistik (berdasarkan Teorema Limit Pusat) hasil analisis ini menjadi sangat kuat dan tidak bias. Selain itu, penggunaan teknik perhitungan Robust Standard Error memastikan hasil pengujian tetap akurat meskipun data memiliki variasi yang cukup kompleks.

3. Strategi Berbasis Data

Produk-produk di Coffee Chain memiliki “nasib” yang berbeda-beda. Kami merekomendasikan manajemen untuk: # a. Memperkuat produk Earl Grey dan Regular Espresso yang sudah terbukti memberikan hasil penjualan dan keuntungan tinggi. # b. Memperbaiki efisiensi produk yang berkinerja rendah (terutama Lemon) agar tidak terus-menerus membebani biaya produksi perusahaan. # c.  Penjualan yang tinggi tidak selalu berarti keuntungan yang tinggi. Perusahaan harus lebih teliti dalam memilih produk mana yang benar-benar memberikan margin keuntungan sehat bagi bisnis.

E. Daftar Pustaka

Muhammad Bayu Nirwana, S.Si., M.Sc. (2024). Dataset Coffee Chain: Sistem Informasi Manajemen (SIM). [Sumber Data Internal]. Program Studi Statistika.
Gujarati, D. N., & Porter, D. C. (2009). Basic Econometrics (5th ed.). McGraw-Hill Irwin.
Montgomery, D. C. (2017). Design and Analysis of Experiments (9th ed.). John Wiley & Sons.
James, G., Witten, D., Hastie, T., & Tibshirani, R. (2013). An Introduction to Statistical Learning. Springer.