1 Pendahuluan

1.1 Latar Belakang

Industri kopi merupakan salah satu sektor pada bidang makanan dan minuman yang terus berkembang dan banyak diminati oleh masyarakat. Banyaknya peminat dalam mengonsumsi kopi membuat semakin banyak coffe shop yang menjadikan lingkungan persaingan semakin ketat. Oleh sebab itu tujuan dari analisis ini adalah untuk membantu para investor atau pemilih usaha coffe shop agar mampu memahami kondisi pasar dan mampu mengatur strategi yang baik dan tepat sasaran.

Setelah diteliti dan dicari tahu, dataset yang saya gunakan dalam analisis ini berasal dari Tableau Community Repository milik Tableau yang sudah umum digunakan untuk latihan. Dataset Coffee Chain berisi data transaksi penjualan produk kopi dan berbagai jenis minuman dari sebuah jaringan kedai kopi di Amerika Serikat. Data terdiri dari 4.248 observasi dan 20 variabel, yang meliputi informasi pasar, jenis produk, anggaran, serta realisasi penjualan dan profit.

1.2 Rumusan Masalah

  1. Bagaimana performa antar market?
  2. Bagaimana tren penjualan yang ada?
  3. Faktor apa yang paling memengaruhi profit/keuntungan?

2 Persiapan Data

2.1 Import Data dan load library

Langkah awal yang perlu kita lakukan adalah load library, untuk semua library yg akan digunakan. Lebih baik lakukan load di awal agar nanti di tengah sudah tidak perlu load library lagi dan meminimalisir eror. Kemudian dilanjutkan juga dengan melakukan impor dataset yang akan digunakan, saya menggunkan dataset yang telah diunduh. Untuk packages import dataset juga disesuaikan dengan jenis dataset yg akan digunakan, karena data yg saya gunakan memiliki format xlsx maka saya menggunakan read_excel.

library(tidyverse)   # Manipulasi data dan visualisasi
library(readxl)      # Membaca file Excel
library(lubridate)   # Mengolah data tanggal
library(corrplot)    # Heatmap korelasi
library(car)         # Uji VIF multikolinearitas
library(lmtest)      # Uji Breusch-Pagan dan Durbin-Watson
library(tseries)     # Uji ADF stasioneritas
library(forecast)    # Dekomposisi time series
library(scales)      # Format label grafik
library(knitr)       # Tabel di HTML
library(kableExtra)  # Styling tabel
df <- read_excel("C:/Users/Asus/OneDrive/Documents/kuliah/SEMESTER 4/SIM2/1. Tugas SIM 2025B - Coffee Chain Datasets/1. Tugas SIM 2025B - Coffee Chain Datasets.xlsx",
                 sheet = "data")

2.2 Eksplorasi Awal

Eksplorasi berikut digunakan untuk mengetahui ukuran data, struktur data, tipe data dan nama data.

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…
## $ Market           <chr> "Central", "Central", "Central", "Central", "Central"…
## $ `Market Size`    <chr> "Major Market", "Major Market", "Major Market", "Majo…
## $ Product          <chr> "Amaretto", "Colombian", "Decaf Irish Cream", "Green …
## $ `Product Line`   <chr> "Beans", "Beans", "Beans", "Leaves", "Beans", "Beans"…
## $ `Product Type`   <chr> "Coffee", "Coffee", "Coffee", "Tea", "Espresso", "Esp…
## $ State            <chr> "Colorado", "Colorado", "Colorado", "Colorado", "Colo…
## $ Type             <chr> "Regular", "Regular", "Decaf", "Regular", "Regular", …
## $ `Budget COGS`    <dbl> 90, 80, 100, 30, 60, 80, 140, 50, 50, 40, 50, 150, 10…
## $ `Budget Margin`  <dbl> 130, 110, 140, 50, 90, 130, 160, 80, 70, 70, 70, 210,…
## $ `Budget Profit`  <dbl> 100, 80, 110, 30, 70, 80, 110, 20, 40, 20, 40, 130, 1…
## $ `Budget Sales`   <dbl> 220, 190, 240, 80, 150, 210, 300, 130, 120, 110, 120,…
## $ COGS             <dbl> 89, 83, 95, 44, 54, 72, 170, 63, 60, 58, 64, 144, 95,…
## $ Inventory        <dbl> 777, 623, 821, 623, 456, 558, 1091, 435, 336, 338, 96…
## $ Margin           <dbl> 130, 107, 139, 56, 80, 108, 171, 87, 80, 72, 76, 201,…
## $ Marketing        <dbl> 24, 27, 26, 14, 15, 23, 47, 57, 19, 22, 19, 47, 30, 7…
## $ Profit           <dbl> 94, 68, 101, 30, 54, 53, 99, 0, 33, 17, 36, 111, 87, …
## $ Sales            <dbl> 219, 190, 234, 100, 134, 180, 341, 150, 140, 130, 140…
## $ `Total Expenses` <dbl> 36, 39, 38, 26, 26, 55, 72, 87, 47, 55, 40, 90, 52, 1…

Kemudian dilanjutkan dengan mengetahui nilai minimum, maximum, mean, median dan quartil untuk beberapa variabel. Rumus-rumus tersebut secara garis besarnya adalah sebagai berikut: Mean(rata-rata) : \[\bar{x} = \frac{1}{n} \sum_{i=1}^{n} x_i\] Median: \[\tilde{x} = \begin{cases} x_{\left(\frac{n+1}{2}\right)} & \text{jika } n \text{ ganjil} \\ \frac{x_{\left(\frac{n}{2}\right)} + x_{\left(\frac{n}{2}+1\right)}}{2} & \text{jika } n \text{ genap} \end{cases}\] Minimum: \[x_{\min} = \min_{1 \leq i \leq n}(x_i)\] Maximum: \[x_{\max} = \max_{1 \leq i \leq n}(x_i)\] Quartil: \[Q_k = x_{\left(\frac{k(n+1)}{4}\right)}, \quad k = 1, 2, 3\]

dan diperoleh hasil sebagai berikut:

df %>%
  select(Sales, Marketing, COGS, `Total Expenses`, Margin, Profit) %>%
  summary() %>%
  kable(caption = "Statistik Deskriptif Variabel Numerik") %>%
  kable_styling(bootstrap_options = c("striped", "hover", "condensed"),
                full_width = FALSE)
Statistik Deskriptif Variabel Numerik
Sales Marketing COGS Total Expenses Margin Profit
Min. : 17 Min. : 0.00 Min. : 0.00 Min. : 10.00 Min. :-302.00 Min. :-638.0
1st Qu.:100 1st Qu.: 13.00 1st Qu.: 43.00 1st Qu.: 33.00 1st Qu.: 52.75 1st Qu.: 17.0
Median :138 Median : 22.00 Median : 60.00 Median : 46.00 Median : 76.00 Median : 40.0
Mean :193 Mean : 31.19 Mean : 84.43 Mean : 54.06 Mean : 104.29 Mean : 61.1
3rd Qu.:230 3rd Qu.: 39.00 3rd Qu.:100.00 3rd Qu.: 65.00 3rd Qu.: 132.00 3rd Qu.: 92.0
Max. :912 Max. :156.00 Max. :364.00 Max. :190.00 Max. : 613.00 Max. : 778.0

2.3 Missing Values

colSums(is.na(df)) %>%
  kable(col.names = "Jumlah NA", caption = "Cek Missing Values per Kolom") %>%
  kable_styling(full_width = FALSE,
                bootstrap_options = c("striped", "hover"))
Cek Missing Values per Kolom
Jumlah NA
Area Code 0
Date 0
Market 0
Market Size 0
Product 0
Product Line 0
Product Type 0
State 0
Type 0
Budget COGS 0
Budget Margin 0
Budget Profit 0
Budget Sales 0
COGS 0
Inventory 0
Margin 0
Marketing 0
Profit 0
Sales 0
Total Expenses 0

Cek missing value dilakukan untuk mengetahui apakah terdapat nilai yang kosong, karena nantinya ini akan memengaruhi pada proses analisis juga. Dan dari hasil cek tersebut, tidak terdapat missing values pada seluruh variabel dataset.

2.4 Konversi Tipe Data

Konversi dilakukan karena masih terdapat beberapa variabel yang memiliki tipe data yang salah dan tidak sesuai tujuan kita.

df <- df %>%
  mutate(
    Date           = as.Date(Date),
    `Product Type` = as.factor(`Product Type`),
    `Market Size`  = as.factor(`Market Size`),
    Market         = as.factor(Market),
    Type           = as.factor(Type),
    ProductType    = `Product Type`,
    MarketSize     = `Market Size`
  )

3 Exploratory Data Analysis (EDA)

3.1 Distribusi Profit

ggplot(df, aes(x = Profit)) +
  geom_histogram(bins = 50, fill = "#2c7bb6", color = "white", alpha = 0.85) +
  geom_vline(xintercept = mean(df$Profit),
             color = "red", linetype = "dashed", linewidth = 1) +
  labs(
    title    = "Distribusi Profit Coffee Chain",
    subtitle = "Garis merah = nilai rata-rata Profit",
    x = "Profit", y = "Frekuensi"
  ) +
  theme_minimal(base_size = 13) +
  theme(plot.title = element_text(face = "bold"))

Distribusi Profit bersifat right-skewed yang berarti mayoritas transaksi menghasilkan profit rendah hingga sedang (ditunjukkan dengan lebih banyak nilai dibawah garis rata-rata), sementara sebagian kecil menghasilkan profit sangat tinggi yang membentuk ekor panjang di kanan.

3.2 Korelasi Variabel

num_vars <- df %>%
  select(Sales, Marketing, COGS, `Total Expenses`, Inventory, Margin, Profit)

corrplot(
  cor(num_vars),
  method      = "color",
  type        = "upper",
  addCoef.col = "black",
  tl.col      = "black",
  tl.srt      = 45,
  number.cex  = 0.75,
  title       = "Matriks Korelasi Variabel Numerik",
  mar         = c(0, 0, 1.5, 0)
)

Margin (r = 0.92) dan Sales (r = 0.80) memiliki korelasi paling kuat terhadap Profit.

3.3 Distribusi Profit per Product Type dan Market Size

ggplot(df, aes(x = `Product Type`, y = Profit, fill = `Market Size`)) +
  geom_boxplot(alpha = 0.8, outlier.alpha = 0.3) +
  scale_fill_manual(values = c("#E07A5F", "#3D405B")) +
  labs(
    title    = "Distribusi Profit berdasarkan Product Type dan Market Size",
    x = "Product Type", y = "Profit", fill = "Market Size"
  ) +
  theme_minimal(base_size = 13) +
  theme(plot.title = element_text(face = "bold"))

Transaksi di Major Market menghasilkan profit lebih tinggi dibanding Small Market pada semua jenis produk.


4 Perbandingan Performa Antar Market dengan analisis variansi (ANOVA)

Perusahaan beroperasi di empat wilayah pasar: Central, East, South, dan West. Aanalisis ini dilakukan untuk mengetahui market mana yang menghasilkan total Sales dan Profit tertinggi, serta apakah terdapat perbedaan profit antar market?

  • H₀: Rata-rata profit keempat market adalah sama
  • H₁: Minimal terdapat satu market dengan rata-rata profit yang berbeda

4.1 Visualisasi Performa per Market

market_summary <- df %>%
  group_by(Market) %>%
  summarise(
    Total_Sales  = sum(Sales),
    Total_Profit = sum(Profit),
    Avg_Margin   = mean(Margin),
    .groups = "drop"
  ) %>%
  arrange(desc(Total_Profit))
ggplot(market_summary,
       aes(x = reorder(Market, -Total_Profit),
           y = Total_Profit, fill = Market)) +
  geom_col(width = 0.6, show.legend = FALSE) +
  geom_text(aes(label = comma(Total_Profit)),
            vjust = -0.5, size = 4, fontface = "bold") +
  scale_y_continuous(labels = comma,
                     expand = expansion(mult = c(0, 0.12))) +
  scale_fill_manual(values = c(
    "Central" = "#9B8EC7",
    "East"    = "#F891BB",
    "South"   = "#F9D0CD",
    "West"    = "#B4D3D9"
  )) +
  labs(
    title    = "Total Profit per Market Region",
    subtitle = "Periode Januari 2012 – Desember 2013",
    x = "Market Region", y = "Total Profit"
  ) +
  theme_minimal(base_size = 13) +
  theme(plot.title = element_text(face = "bold"))

ggplot(df, aes(x = Market, y = Profit, fill = Market)) +
  geom_boxplot(show.legend = FALSE, outlier.alpha = 0.3) +
  scale_fill_manual(values = c(
    "Central" = "#9B8EC7",
    "East"    = "#F891BB",
    "South"   = "#F9D0CD",
    "West"    = "#B4D3D9"
  )) +
  scale_y_continuous(labels = comma) +
  labs(
    title    = "Distribusi Profit per Market Region",
    subtitle = "Setiap titik mewakili satu transaksi",
    x = "Market Region", y = "Profit"
  ) +
  theme_minimal(base_size = 13) +
  theme(plot.title = element_text(face = "bold"))

market_summary %>%
  mutate(
    Total_Sales  = comma(Total_Sales),
    Total_Profit = comma(Total_Profit),
    Avg_Margin   = round(Avg_Margin, 2)
  ) %>%
  rename(
    "Market"            = Market,
    "Total Sales"       = Total_Sales,
    "Total Profit"      = Total_Profit,
    "Rata-rata Margin"  = Avg_Margin
  ) %>%
  kable(caption = "Ringkasan Performa per Market Region") %>%
  kable_styling(bootstrap_options = c("striped", "hover"),
                full_width = FALSE)
Ringkasan Performa per Market Region
Market Total Sales Total Profit Rata-rata Margin
Central 265,045 93,852 108.82
West 272,264 73,996 104.21
East 178,576 59,217 111.42
South 103,926 32,478 86.00
  • Market Central mencatat total Profit tertinggi, diikuti West, East, dan South.
  • Boxplot menunjukkan adanya outlier di semua region, terutama transaksi dengan profit negatif. ## One-Way ANOVA: Profit antar Market
anova_market <- aov(Profit ~ Market, data = df)
summary(anova_market)
##               Df   Sum Sq Mean Sq F value   Pr(>F)    
## Market         3   288811   96270   9.361 3.64e-06 ***
## Residuals   4244 43644825   10284                     
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

4.2 Uji Tukey

tukey_market <- TukeyHSD(anova_market)
tukey_market_df <- as.data.frame(tukey_market$Market) %>%
  rownames_to_column("Pasangan") %>%
  rename(
    Selisih       = diff,
    `CI Bawah`    = lwr,
    `CI Atas`     = upr,
    `p-value adj` = `p adj`
  ) %>%
  mutate(Signifikan = ifelse(`p-value adj` < 0.05, "Ya ✓", "Tidak"))

tukey_market_df %>%
  kable(digits = 3, caption = "Post-Hoc Tukey HSD: Profit antar Market") %>%
  kable_styling(bootstrap_options = c("striped", "hover"),
                full_width = FALSE) %>%
  row_spec(which(tukey_market_df$Signifikan == "Ya ✓"),
           background = "#E8F5E9")
Post-Hoc Tukey HSD: Profit antar Market
Pasangan Selisih CI Bawah CI Atas p-value adj Signifikan
East-Central -3.145 -14.416 8.126 0.890 Tidak
South-Central -21.500 -33.813 -9.187 0.000 Ya ✓
West-Central -14.774 -24.828 -4.720 0.001 Ya ✓
South-East -18.355 -31.681 -5.030 0.002 Ya ✓
West-East -11.629 -22.900 -0.358 0.040 Ya ✓
West-South 6.726 -5.587 19.040 0.497 Tidak

Hasil One-Way ANOVA: Karena nilai p-value < 0,05, Maka H₀ ditolak yang berarti terdapat perbedaan rata-rata profit yang signifikan antar market. Uji Tukey mengidentifikasi pasangan market mana yang berbeda secara spesifik — baris hijau pada tabel = pasangan yang berbeda signifikan.

4.3 Two-Way ANOVA: Product Type × Market Size

anova_2way <- aov(Profit ~ ProductType * MarketSize, data = df)
summary(anova_2way)
##                          Df   Sum Sq Mean Sq F value  Pr(>F)    
## ProductType               3   141680   47227   5.006 0.00182 ** 
## MarketSize                1  2641586 2641586 279.988 < 2e-16 ***
## ProductType:MarketSize    3  1147469  382490  40.541 < 2e-16 ***
## Residuals              4240 40002902    9435                    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
df %>%
  group_by(ProductType, MarketSize) %>%
  summarise(Mean_Profit = mean(Profit), .groups = "drop") %>%
  ggplot(aes(x = ProductType, y = Mean_Profit,
             color = MarketSize, group = MarketSize)) +
  geom_line(linewidth = 1.3) +
  geom_point(size = 3.5) +
  scale_color_manual(values = c("#E07A5F", "#3D405B")) +
  labs(
    title    = "Interaction Plot: Rata-rata Profit",
    subtitle = "Product Type × Market Size",
    x = "Product Type", y = "Rata-rata Profit",
    color = "Market Size"
  ) +
  theme_minimal(base_size = 13) +
  theme(plot.title = element_text(face = "bold"))

Hasil Two-Way ANOVA mengonfirmasi bahwa Major Market secara konsisten menghasilkan profit jauh lebih tinggi dari Small Market pada semua jenis produk. Interaction effect yang signifikan menunjukkan bahwa dampak Market Size berbeda-beda tergantung jenis produknya.


5 Tren Penjualan dari Waktu ke Waktu

Analisis tren bertujuan melihat pola perubahan Sales dan Profit secara bulanan selama periode 2012–2013, termasuk mendeteksi adanya pola musiman (seasonality).

5.1 Persiapan Data

Karena kita mau melihat tren waktu ke waktu dan karena datanya berisi transaksi tiap hari maka dikelompokkan per bulan agar lebih mudahkan dalam visualisasi dan analisis.

df_tren_total <- df %>%
  mutate(Periode = floor_date(Date, "month")) %>%
  group_by(Periode) %>%
  summarise(
    Total_Sales     = sum(Sales),
    Total_Profit    = sum(Profit),
    Total_Marketing = sum(Marketing),
    .groups = "drop"
  )

df_tren <- df %>%
  mutate(Periode = floor_date(Date, "month")) %>%
  group_by(Periode, ProductType) %>%
  summarise(
    Total_Sales  = sum(Sales),
    Total_Profit = sum(Profit),
    .groups = "drop"
  )

df_tren_total %>%
  rename(Bulan = Periode, Sales = Total_Sales,
         Profit = Total_Profit, Marketing = Total_Marketing) %>%
  kable(caption = "Ringkasan Bulanan: Sales, Profit, dan Marketing") %>%
  kable_styling(bootstrap_options = c("striped", "hover"),
                full_width = FALSE)
Ringkasan Bulanan: Sales, Profit, dan Marketing
Bulan Sales Profit Marketing
2012-01-01 31555 8041 5223
2012-02-01 32092 8369 5289
2012-03-01 32245 8365 5327
2012-04-01 32943 8670 5421
2012-05-01 33692 8947 5530
2012-06-01 35125 9571 5765
2012-07-01 36161 9905 5985
2012-08-01 36029 9566 6046
2012-09-01 33092 8508 5491
2012-10-01 32849 8674 5388
2012-11-01 32003 8399 5263
2012-12-01 33373 8811 5509
2013-01-01 35316 12524 5223
2013-02-01 34192 12419 5289
2013-03-01 34355 12415 5327
2013-04-01 35112 12863 5421
2013-05-01 33394 12348 5530
2013-06-01 34807 13218 5765
2013-07-01 35830 13671 5985
2013-08-01 35707 13205 6046
2013-09-01 35269 12627 5491
2013-10-01 34987 12878 5388
2013-11-01 34103 12460 5263
2013-12-01 35580 13089 5509

5.2 Grafik

  1. Pertama membuat visualisasi untuk melihat pola jumlah total penjualan (sales) setiap bulannya.
ggplot(df_tren_total, aes(x = Periode, y = Total_Sales)) +
  geom_line(color = "#2c7bb6", linewidth = 1.2) +
  geom_point(color = "#2c7bb6", size = 2.5) +
  scale_x_date(date_breaks = "3 months", date_labels = "%b %Y") +
  scale_y_continuous(labels = comma) +
  labs(
    title    = "Tren Total Penjualan (Sales) Bulanan",
    subtitle = "Periode Januari 2012 – Desember 2013",
    x = "Periode", y = "Total Sales"
  ) +
  theme_minimal(base_size = 13) +
  theme(plot.title  = element_text(face = "bold"),
        axis.text.x = element_text(angle = 45, hjust = 1))

  1. kemudian membuat visualisasi untuk melihat pola pembelian setiap produk pada setiap bulannya.
ggplot(df_tren, aes(x = Periode, y = Total_Sales, color = ProductType)) +
  geom_line(linewidth = 1.1) +
  geom_point(size = 2) +
  scale_x_date(date_breaks = "3 months", date_labels = "%b %Y") +
  scale_y_continuous(labels = comma) +
  scale_color_brewer(palette = "Set3") +
  labs(
    title    = "Tren Penjualan per Jenis Produk",
    subtitle = "Coffee, Tea, Espresso, dan Herbal Tea",
    x = "Periode", y = "Total Sales", color = "Jenis Produk"
  ) +
  theme_minimal(base_size = 13) +
  theme(plot.title  = element_text(face = "bold"),
        axis.text.x = element_text(angle = 45, hjust = 1))

  1. Dilanjut membuat visualisasi untuk melihat pola jumlah keuntungan/profit pada setiap bulannya.
ggplot(df_tren_total, aes(x = Periode, y = Total_Profit)) +
  geom_area(fill = "#FBEFEF", alpha = 0.4) +
  geom_line(color = "#F5AFAF", linewidth = 1.2) +
  geom_point(color = "#F5AFAF", size = 2.5) +
  scale_x_date(date_breaks = "3 months", date_labels = "%b %Y") +
  scale_y_continuous(labels = comma) +
  labs(
    title    = "Tren Total Profit Bulanan",
    subtitle = "Periode Januari 2012 – Desember 2013",
    x = "Periode", y = "Total Profit"
  ) +
  theme_minimal(base_size = 13) +
  theme(plot.title  = element_text(face = "bold"),
        axis.text.x = element_text(angle = 45, hjust = 1))

  1. Terakhir membandingkan pengeluaran marketing dengan profit setiap bulannya
ggplot(df_tren_total, aes(x = Periode)) +
  geom_col(aes(y = Total_Marketing), fill = "#81B29A", alpha = 0.8) +
  geom_line(aes(y = Total_Profit), color = "#E07A5F", linewidth = 1.2) +
  geom_point(aes(y = Total_Profit), color = "#E07A5F", size = 2.5) +
  scale_x_date(date_labels = "%b %Y", date_breaks = "2 months") +
  scale_y_continuous(labels = comma) +
  labs(
    title    = "Pengeluaran Marketing (batang) vs Profit (garis) Bulanan",
    x = "Bulan", y = "Nilai"
  ) +
  theme_minimal(base_size = 13) +
  theme(plot.title  = element_text(face = "bold"),
        axis.text.x = element_text(angle = 45, hjust = 1))

5.3 Dekomposisi

Dekomposisi adalah teknik memecah data menjadi beberapa komponen penyusun, supaya kita bisa melihat masing-masing pola secara terpisah dan lebih jelas. Data tersebut dipecah menjadi Data asli (observed),trend, seasonal dan sisa

ts_profit <- ts(df_tren_total$Total_Profit,
                start = c(2012, 1), frequency = 12)

decomp <- decompose(ts_profit, type = "additive")
plot(decomp, title = "Dekomposisi Time Series: Total Profit Bulanan")

5.4 Interpretasi

Trend > - Total Sales menunjukkan adanya pola musiman dalam melakukan transaksi yang mungkin hal ini dipengaruhi oleh musim/cuaca yang ada di Amerika. > - Coffee secara konsisten menjadi produk dengan penjualan tertinggi sepanjang periode jika dibandingkan dengan minuman yang lain. > - Profit/Keuntungan juga terlihat terus meningkat, meskipun terkadang menurun dibeberapa waktu (yg disebabkan oleh faktor lain seperti cuaca) akan tetapi secara garis besar profit terus meningkat. > - Pengeluaran Marketing dan Profit bergerak saling memberikan timbal balik,yang artinya investasi marketing berkontribusi positif terhadap profit.


6 Faktor yang Mempengaruhi Profit

Pada tahap ini dilakukan analisis yang ditujukan untuk mengetahui variabel apa yang paling berpengaruh terhadap Profit.

Bentuk umum persamaan regresi linear berganda: \[Y = \beta_0 + \beta_1 X_1 + \beta_2 X_2 + \beta_3 X_3 + \cdots + \beta_p X_p + \varepsilon\] dan pada kasus ini kita akan membuktikan rumus: \[Profit = \beta_0 + \beta_1 \cdot Sales + \beta_2 \cdot Marketing + \beta_3 \cdot COGS + \beta_4 \cdot Total\ Expenses + \varepsilon\]

6.1 Eksplorasi Korelasi

ggplot(df, aes(x = Sales, y = Profit)) +
  geom_point(alpha = 0.25, color = "#4575b4") +
  geom_smooth(method = "lm", color = "red", se = TRUE) +
  scale_x_continuous(labels = comma) +
  scale_y_continuous(labels = comma) +
  labs(
    title    = "Hubungan antara Sales dan Profit",
    subtitle = "Garis merah = garis regresi linear",
    x = "Sales", y = "Profit"
  ) +
  theme_minimal(base_size = 13) +
  theme(plot.title = element_text(face = "bold"))

6.2 Membangun Model Regresi

model_regresi <- lm(
  Profit ~ Sales + Marketing + COGS + `Total Expenses`,
  data = df
)
summary(model_regresi)
## 
## Call:
## lm(formula = Profit ~ Sales + Marketing + COGS + `Total Expenses`, 
##     data = df)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -112.028   -5.748    0.526    5.525  105.228 
## 
## Coefficients:
##                   Estimate Std. Error  t value Pr(>|t|)    
## (Intercept)       2.366873   0.705850    3.353 0.000806 ***
## Sales             1.208316   0.003721  324.744  < 2e-16 ***
## Marketing         0.195850   0.040466    4.840 1.35e-06 ***
## COGS             -1.241869   0.010250 -121.156  < 2e-16 ***
## `Total Expenses` -1.400421   0.031161  -44.942  < 2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 16.86 on 4243 degrees of freedom
## Multiple R-squared:  0.9726, Adjusted R-squared:  0.9725 
## F-statistic: 3.76e+04 on 4 and 4243 DF,  p-value: < 2.2e-16

6.3 Tabel Koefisien Regresi

coef_df <- as.data.frame(summary(model_regresi)$coefficients)
coef_df <- round(coef_df, 4)
colnames(coef_df) <- c("Koefisien", "Std. Error", "t-value", "p-value")

coef_df %>%
  kable(caption = "Koefisien Model Regresi Linear Berganda") %>%
  kable_styling(bootstrap_options = c("striped", "hover"),
                full_width = FALSE) %>%
  row_spec(which(coef_df$`p-value` < 0.05),
           bold = TRUE, color = "white", background = "#CBDCEB")
Koefisien Model Regresi Linear Berganda
Koefisien Std. Error t-value p-value
(Intercept) 2.3669 0.7059 3.3532 8e-04
Sales 1.2083 0.0037 324.7442 0e+00
Marketing 0.1958 0.0405 4.8398 0e+00
COGS -1.2419 0.0103 -121.1563 0e+00
Total Expenses -1.4004 0.0312 -44.9416 0e+00

Interpretasi Koefisien: - Sales berkoefisien positif signifikan yang berarti setiap kenaikan 1 unit Sales meningkatkan Profit secara bermakna. - COGS berkoefisien negatif signifikan berarti semakin tinggi biaya produksi maka semakin rendah Profit. - Marketing berkoefisien positif signifikan investasi marketing terbukti berkontribusi pada peningkatan Profit. - Total Expenses berkoefisien negatif signifikan yang berarti biaya operasional yang tinggi akan menurunkan Profit. - Nilai R² Adjusted yang sangat tinggi menunjukkan model mampu menjelaskan proporsi besar variasi Profit.

6.4 Visualisasi: Actual vs Predicted Profit

df_pred <- df %>%
  mutate(
    Predicted = predict(model_regresi),
    Residual  = Profit - Predicted
  )

ggplot(df_pred, aes(x = Predicted, y = Profit)) +
  geom_point(alpha = 0.25, color = "#2c7bb6") +
  geom_abline(slope = 1, intercept = 0,
              color = "red", linetype = "dashed", linewidth = 1) +
  labs(
    title    = "Actual vs Predicted Profit",
    subtitle = "Garis merah = prediksi sempurna",
    x = "Predicted Profit", y = "Actual Profit"
  ) +
  theme_minimal(base_size = 13) +
  theme(plot.title = element_text(face = "bold"))

Sebagian besar titik data mengikuti garis merah yang menunjukkan prediksi model cukup akurat.

6.5 Uji Asumsi Regresi

6.5.1 Normalitas Residual (Kolmogorov-Smirnov)

ks_test <- ks.test(df_pred$Residual, "pnorm",
                   mean = mean(df_pred$Residual),
                   sd   = sd(df_pred$Residual))

data.frame(
  Uji        = "Kolmogorov-Smirnov",
  Statistik  = round(ks_test$statistic, 4),
  `p-value`  = formatC(ks_test$p.value, format = "e", digits = 3),
  Kesimpulan = ifelse(ks_test$p.value > 0.05,
                      "Normal",
                      "Tidak Normal"),
  check.names = FALSE
) %>%
  kable(caption = "Uji Normalitas Residual") %>%
  kable_styling(full_width = FALSE,
                bootstrap_options = c("striped", "hover"))
Uji Normalitas Residual
Uji Statistik p-value Kesimpulan
D Kolmogorov-Smirnov 0.1551 3.616e-89 Tidak Normal

Dari hasil uji normalitas diperoleh bahwa residunya tidak normal, akan tetapi jika kita melihat jumlah observasi yang sangat besar yaitu n = 4.248 kita dapat menggunakan CLT. Central Limit Theorem (CLT) mengatakan bahwa ketika sampel besar diambil secara acak, maka distribusi rata-rata sampel akan mendekati normal sehingga hasil inferensi tetap valid. Sehingga hal ini dapat diabaikan.

6.5.2 Homoskedastisitas (Breusch-Pagan)

bp_test <- bptest(model_regresi)

data.frame(
  Uji        = "Breusch-Pagan",
  Statistik  = round(bp_test$statistic, 4),
  `p-value`  = formatC(bp_test$p.value, format = "e", digits = 3),
  Kesimpulan = ifelse(bp_test$p.value > 0.05,
                      "Homoskedastis ✓",
                      "Heteroskedastis ✗"),
  check.names = FALSE
) %>%
  kable(caption = "Uji Homoskedastisitas (Breusch-Pagan)") %>%
  kable_styling(full_width = FALSE,
                bootstrap_options = c("striped", "hover"))
Uji Homoskedastisitas (Breusch-Pagan)
Uji Statistik p-value Kesimpulan
BP Breusch-Pagan 994.7779 4.834e-214 Heteroskedastis ✗

Dari hasil uji homoskedastisitas menunjukkan bahawa terdapat Heteroskedastisitas yang hanya akan memengaruhi standard error.

6.5.3 Multikolinearitas (VIF)

vif_vals <- vif(model_regresi)

data.frame(
  Variabel   = names(vif_vals),
  VIF        = round(vif_vals, 3),
  Kesimpulan = ifelse(vif_vals > 10,
                      "Multikolinearitas ✗",
                      "Aman ✓")
) %>%
  kable(caption = "Variance Inflation Factor (VIF)") %>%
  kable_styling(full_width = FALSE,
                bootstrap_options = c("striped", "hover")) %>%
  row_spec(which(vif_vals > 10),
           bold = TRUE, color = "white", background = "#C0E1D2")
Variance Inflation Factor (VIF)
Variabel VIF Kesimpulan
Sales Sales 4.727 Aman ✓
Marketing Marketing 17.874 Multikolinearitas ✗
COGS COGS 7.102 Aman ✓
Total Expenses Total Expenses 15.191 Multikolinearitas ✗

Dari hasil uji Multikolinearitas, kita perlu berhati hati dengan variabel marketing dan total expenses, karena keduanya memiliki nilai VIF yang > 10.

6.5.4 Autokorelasi (Durbin-Watson)

dw_test <- dwtest(model_regresi)

data.frame(
  Uji        = "Durbin-Watson",
  Statistik  = round(dw_test$statistic, 4),
  `p-value`  = round(dw_test$p.value, 4),
  Kesimpulan = ifelse(
    dw_test$statistic >= 1.5 & dw_test$statistic <= 2.5,
    "Tidak ada autokorelasi ✓",
    "Terdapat autokorelasi ✗"
  ),
  check.names = FALSE
) %>%
  kable(caption = "Uji Autokorelasi (Durbin-Watson)") %>%
  kable_styling(full_width = FALSE,
                bootstrap_options = c("striped", "hover"))
Uji Autokorelasi (Durbin-Watson)
Uji Statistik p-value Kesimpulan
DW Durbin-Watson 1.7888 0 Tidak ada autokorelasi ✓

Hasil uji autokorelasi memberikan hasil 1,79 yang menandakan tidak ada autokorelasi antar residual, artinya residual bersifat independen satu sama lain.

6.5.5 Ringkasan Uji Asumsi

data.frame(
  No      = 1:4,
  Asumsi  = c("Normalitas Residual", "Homoskedastisitas",
              "Multikolinearitas", "Autokorelasi"),
  Metode  = c("Kolmogorov-Smirnov", "Breusch-Pagan",
              "VIF", "Durbin-Watson"),
  Status  = c(
    "⚠ Tidak normal — CLT berlaku (n besar)",
    ifelse(bp_test$p.value > 0.05,
           "✓ Terpenuhi", "⚠ Heteroskedastis — limitasi model"),
    ifelse(all(vif_vals < 10),
           "✓ Terpenuhi", "⚠ Ada multikolinearitas — limitasi model"),
    ifelse(dw_test$statistic >= 1.5 & dw_test$statistic <= 2.5,
           "✓ Terpenuhi", "⚠ Ada autokorelasi")
  )
) %>%
  kable(caption = "Ringkasan Hasil Uji Asumsi Regresi") %>%
  kable_styling(full_width = FALSE,
                bootstrap_options = c("striped", "hover")) %>%
  column_spec(4, bold = TRUE)
Ringkasan Hasil Uji Asumsi Regresi
No Asumsi Metode Status
1 Normalitas Residual Kolmogorov-Smirnov ⚠ Tidak normal — CLT berlaku (n besar)
2 Homoskedastisitas Breusch-Pagan ⚠ Heteroskedastis — limitasi model
3 Multikolinearitas VIF ⚠ Ada multikolinearitas — limitasi model
4 Autokorelasi Durbin-Watson ✓ Terpenuhi

7 Kesimpulan

7.1 Ringkasan

Ringkasan Hasil Analisis
No Rumusan Hasil
1 Performa antar Market Market Central mencatat profit tertinggi. Perbedaan antar market cukup signifikan secara statistik. Major Market secara konsisten lebih menghasilkan profit dari Small Market.
2 Tren Penjualan Tren Sales dan Profit meningkat dari 2012 ke 2013 dan cenderung memiliki pola musiman. Coffee mendominasi penjualan sepanjang periode.
3 Faktor yang mempengaruhi Profit Sales berpengaruh positif terkuat terhadap Profit. COGS dan Total Expenses berpengaruh negatif signifikan. R² sangat tinggi menunjukkan model fit baik.

7.2 Rekomendasi

  1. Dapat lebih peduli dan mengendalikan COGS dan Total Expenses karena penurunan kedua faktor tersebut akan berdampak langsung pada peningkatan Profit.
  2. Lebih memprioritaskan Major market melihat peluangnya yang jauh lebih menguntungkan.
  3. Fokus dan buat inovasi inovasi lagi untuk produk Coffee, karena itu hal yang paling diminati.

Sistem Informasi Manajemen - G Universitas Sebelas Maret