Analisis ini dilakukan pada dataset transaksi Restoran Ayam Serayu selama periode 2023–2025 (sumber). Dataset ini mencakup informasi penting seperti waktu transaksi, outlet, jenis layanan, menu, harga, jumlah pembelian, hingga metode pembayaran.
Permasalahan utama yang ingin dikaji dalam analisis ini adalah:
Tujuan dari analisis ini adalah untuk mengeksplorasi data secara visual sehingga dapat memberikan insight strategis bagi pengelola restoran dalam pengambilan keputusan berbasis data.
Dataset dimuat menggunakan fungsi read.csv() dari file
lokal. Selanjutnya, fungsi colnames() digunakan untuk
melihat struktur awal nama variabel dalam dataset sebelum dilakukan
proses pembersihan dan transformasi data.
# Memuat dataset
resto_data <- read.csv("C:/Users/LENOVO/OneDrive/ドキュメント/4 VISDAT/AyamSerayu_3Years_Transaction_Data.csv")
colnames(resto_data)
## [1] "Tanggal...Waktu" "ID.Struk" "Outlet"
## [4] "Tipe.Penjualan" "Kasir" "Nama.Produk"
## [7] "Kategori" "Jumlah.Produk" "Harga.Produk"
## [10] "Penjualan.Kotor" "Total" "Metode.Pembayaran"
## [13] "Status.Pembayaran" "Diskon" "Pajak"
Dataset ini merupakan data sintetis hasil simulasi yang terdiri dari lebih dari 626.311 baris data dengan total 15 variabel yang merepresentasikan transaksi penjualan. Beberapa variabel utama antara lain:
Waktu: waktu transaksiOutlet: lokasi cabang restoranMenu: nama produkJumlah: jumlah item yang dibeliHarga: harga per produkTotal: total pembayaranMetode: metode pembayaranUntuk mempermudah analisis, dilakukan proses feature
engineering seperti mengubah format waktu, menambahkan variabel
bulan (Bulan), hari (Hari), serta kategori
waktu (Jam). Proses ini bertujuan untuk mempermudah
analisis berbasis waktu (time-based analysis).
resto_data <- resto_data %>%
rename(
Waktu = Tanggal...Waktu,
Layanan = Tipe.Penjualan,
Menu = Nama.Produk,
Jumlah = Jumlah.Produk,
Harga = Harga.Produk,
Subtotal = Penjualan.Kotor,
Metode = Metode.Pembayaran,
Status = Status.Pembayaran
)
resto_data <- resto_data %>%
mutate(
Waktu = ymd_hms(Waktu),
Bulan = format(Waktu, "%b %Y"),
Tanggal = floor_date(Waktu, "month") %>% as.Date(),
Hari = wday(Waktu, label = TRUE, abbr = FALSE, locale = "id_ID"),
Hari = factor(Hari, levels = c("Senin", "Selasa", "Rabu", "Kamis", "Jumat", "Sabtu", "Minggu")),
Jam = case_when(
hour(Waktu) >= 0 & hour(Waktu) <= 10 ~ "Pagi (00:00-10:59)",
hour(Waktu) >= 11 & hour(Waktu) <= 14 ~ "Siang (11:00-14:59)",
hour(Waktu) >= 15 & hour(Waktu) <= 18 ~ "Sore (15:00-17:59)",
hour(Waktu) >= 19 & hour(Waktu) <= 23 ~ "Malam (18:00-23:59)"
),
Outlet = case_when(
Outlet == "AYAM SERAYU - PUSAT" ~ "Pusat",
Outlet == "AYAM SERAYU - CABANG 1" ~ "Cabang 1",
Outlet == "AYAM SERAYU - CABANG 2" ~ "Cabang 2"
)
)
Hasil proses recode menghasilkan dataset yang lebih
terstruktur dan mudah dianalisis. Variabel waktu telah dikonversi ke
format yang sesuai (datetime), serta ditambahkan variabel
turunan seperti bulan, hari, dan kategori waktu (pagi, siang,
sore, malam).
Selain itu, nama outlet juga telah disederhanakan menjadi Pusat, Cabang 1, dan Cabang 2 untuk meningkatkan keterbacaan visualisasi. Transformasi ini sangat penting dalam proses analisis karena memungkinkan eksplorasi data yang lebih mendalam dan informatif.
glimpse(resto_data)
## Rows: 626,311
## Columns: 19
## $ Waktu <dttm> 2023-01-01 00:51:19, 2023-01-01 00:51:19, 2023-01-01 03:33:0…
## $ ID.Struk <chr> "TRX-20230101-8589", "TRX-20230101-8589", "TRX-20230101-3069"…
## $ Outlet <chr> "Cabang 2", "Cabang 2", "Pusat", "Pusat", "Pusat", "Pusat", "…
## $ Layanan <chr> "Dine in", "Dine in", "Dine in", "Dine in", "Dine in", "Dine …
## $ Kasir <chr> "Rina", "Rina", "Budi", "Budi", "Budi", "Budi", "Budi", "Nabi…
## $ Menu <chr> "Ayam Bakar Madu", "Air Mineral", "Cah Kangkung", "Kulit Ayam…
## $ Kategori <chr> "Makanan", "Minuman", "Makanan", "Makanan", "Makanan", "Makan…
## $ Jumlah <int> 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1…
## $ Harga <int> 31000, 5000, 12000, 19000, 20000, 29000, 31000, 5000, 12000, …
## $ Subtotal <int> 31000, 5000, 12000, 19000, 40000, 29000, 62000, 5000, 12000, …
## $ Total <int> 36000, 36000, 162000, 162000, 162000, 162000, 162000, 46000, …
## $ Metode <chr> "Tunai", "QRIS", "QRIS", "Tunai", "Debit", "Tunai", "Debit", …
## $ Status <chr> "Success", "Success", "Success", "Success", "Success", "Succe…
## $ Diskon <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0…
## $ Pajak <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0…
## $ Bulan <chr> "Jan 2023", "Jan 2023", "Jan 2023", "Jan 2023", "Jan 2023", "…
## $ Tanggal <date> 2023-01-01, 2023-01-01, 2023-01-01, 2023-01-01, 2023-01-01, …
## $ Hari <ord> Minggu, Minggu, Minggu, Minggu, Minggu, Minggu, Minggu, Mingg…
## $ Jam <chr> "Pagi (00:00-10:59)", "Pagi (00:00-10:59)", "Pagi (00:00-10:5…
Tabel di atas menampilkan sebagian data dari dataset setelah proses pembersihan. Variabel yang digunakan dalam analisis ini terdiri dari:
Outlet, Layanan,
Menu, Kategori, MetodeJumlah, Harga,
TotalWaktu, Tanggal,
Hari, JamKombinasi variabel ini memungkinkan analisis dilakukan dari berbagai sudut pandang, baik secara kategorik maupun kontinu.
datatable(head(resto_data, 50), options = list(pageLength = 5, width = '100%'))
Setelah seluruh proses pembersihan dan transformasi dilakukan, dataset telah siap digunakan untuk tahap eksplorasi dan visualisasi data guna menjawab pertanyaan penelitian yang telah dirumuskan sebelumnya.
Visualisasi kategorik digunakan untuk menganalisis data yang berbentuk kategori atau kelompok, seperti jenis layanan, outlet, maupun menu. Tujuan dari visualisasi ini adalah untuk memahami distribusi dan proporsi data dalam setiap kategori serta mengidentifikasi kategori yang dominan.
Jenis layanan apa yang paling diminati oleh pelanggan?
metode_ramai <- resto_data %>%
group_by(Layanan) %>%
summarise(
Jumlah_Transaksi = n_distinct(ID.Struk),
.groups = "drop"
) %>%
mutate(
Persentase = Jumlah_Transaksi / sum(Jumlah_Transaksi) * 100,
Label = paste0(Layanan, "\n", round(Persentase, 1), "%")
)
ggplot(metode_ramai, aes(x = "", y = Jumlah_Transaksi, fill = Layanan)) +
geom_col(width = 2) +
coord_polar(theta = "y") +
geom_text(aes(label = Label), position = position_stack(vjust = 0.5), size = 4) +
scale_fill_manual(values = c(
"Dine in" = "#c1460d",
"Online" = "#eca129",
"Take Away" = "#e7ccb6"
)) +
labs(
title = "Proporsi Jenis Layanan Restoran Ayam Serayu",
subtitle = "Berdasarkan preferensi pelanggan",
fill = "Jenis Layanan"
) +
theme_void()
Visualisasi ini menggunakan pie chart untuk
menggambarkan proporsi jenis layanan yang digunakan oleh pelanggan,
yaitu Dine in, Online, dan Take Away.
Variabel yang digunakan adalah Layanan sebagai kategori dan
jumlah transaksi sebagai ukuran.
Berdasarkan grafik, terlihat bahwa layanan Dine in mendominasi dengan proporsi sekitar 50%, diikuti oleh Online dan Take Away. Hal ini menunjukkan bahwa sebagian besar pelanggan masih lebih memilih makan langsung di tempat dibandingkan menggunakan layanan lainnya.
Temuan ini mengindikasikan bahwa pengalaman makan di tempat masih menjadi faktor penting bagi pelanggan. Oleh karena itu, restoran perlu menjaga kualitas layanan dine-in, seperti kenyamanan tempat dan kecepatan pelayanan, sambil tetap mengembangkan layanan online untuk menjangkau lebih banyak pelanggan.
Visualisasi bivariat digunakan untuk menganalisis hubungan antara dua variabel dalam dataset. Tujuan utama dari visualisasi ini adalah untuk melihat apakah terdapat pola, perbedaan, atau hubungan tertentu antara variabel tersebut.
Dalam analisis ini, visualisasi bivariat digunakan untuk
membandingkan variabel seperti Outlet, Menu,
Kasir, dan Metode terhadap jumlah transaksi
atau jumlah pembelian. Dengan pendekatan ini, kita dapat
mengidentifikasi kategori mana yang paling dominan
serta melihat variasi performa antar kelompok.
Jenis grafik yang umum digunakan dalam visualisasi bivariat adalah grouped bar chart, karena mampu memperlihatkan perbandingan antar kategori secara jelas dan informatif.
Bagaimana variasi penggunaan metode pembayaran dari para pelanggan? Bagaimana pula distribusi performa kasir yang melayani tiap metode pembayaran?
top_kasir <- resto_data %>%
group_by(Metode, Kasir) %>%
summarise(
Jumlah = n_distinct(ID.Struk),
.groups = "drop"
) %>%
group_by(Metode) %>%
slice_max(order_by = Jumlah, n = 3) %>%
# Langkah kunci: Urutkan Kasir berdasarkan Jumlah (descending) di tiap Layanan
mutate(Kasir_Order = reorder_within(Kasir, -Jumlah, Metode)) %>%
ungroup()
ggplot(top_kasir, aes(x = Metode, y = Jumlah, fill = Kasir, group = Kasir_Order)) +
geom_col(position = position_dodge(width = 0.9)) +
scale_fill_manual(values = c(
"Rina" = "#e7ccb6",
"Budi" = "#eca129",
"Fikri" = "#c1460d",
"Siti" = "#7f201c"
)) +
labs(
title = "Top 3 Kasir Restoran Ayam Serayu Terproduktif",
subtitle = "Perbandingan kasir yang paling aktif melayani di tiap metode pembayaran",
x = "Metode Pembayaran",
y = "Jumlah Transaksi",
fill = "Nama Kasir"
) +
theme_minimal()
Visualisasi ini menggunakan grouped bar chart untuk
membandingkan jumlah pelanggan yang dilayani oleh masing-masing kasir
pada setiap jenis layanan. Variabel yang digunakan adalah
Layanan sebagai kategori utama, Jumlah sebagai
ukuran, dan Kasir sebagai pembeda.
Berdasarkan grafik, terlihat bahwa distribusi jumlah pelanggan yang dilayani oleh setiap kasir pada masing-masing layanan cenderung relatif merata. Tidak terdapat perbedaan yang signifikan antar kasir dalam melayani pelanggan, baik pada layanan Dine in, Online, maupun Take Away.
Hal ini menunjukkan bahwa sistem operasional restoran telah berjalan dengan baik dalam mendistribusikan beban kerja secara seimbang antar kasir. Dengan kata lain, tidak ada kasir yang terlalu terbebani maupun terlalu sedikit melayani pelanggan.
Insight ini mengindikasikan adanya efisiensi dalam manajemen operasional, khususnya dalam pembagian tugas kasir. Ke depan, restoran dapat mempertahankan sistem ini, serta mengevaluasi kinerja kasir secara lebih mendalam, misalnya dari segi kecepatan pelayanan atau kepuasan pelanggan.
Visualisasi kontinu digunakan untuk menganalisis
variabel numerik yang memiliki rentang nilai tertentu, seperti
Harga, Jumlah, dan Total. Tujuan
dari visualisasi ini adalah untuk memahami pola distribusi dan
penyebaran data.
Dalam analisis ini, digunakan histogram untuk melihat distribusi pendapatan total per transaksi. Visualisasi ini membantu dalam mengidentifikasi apakah data memiliki distribusi normal, miring (skewed), atau memiliki nilai ekstrem (outlier).
Dengan memahami distribusi data, kita dapat memperoleh insight penting terkait perilaku pelanggan, seperti kecenderungan nilai transaksi dan potensi segmentasi pelanggan berdasarkan tingkat pembelian.
“Bagaimana distribusi pendapatan total restoran?”
ggplot(resto_data, aes(x = Total)) +
geom_histogram(fill = "#7f201c", bins = 30, color = "grey") +
scale_x_continuous(labels = comma) +
labs(
title = "Distribusi Pendapatan Total Restoran Ayam Serayu",
subtitle = "Berdasarkan hasil penjualan (per transaksi) seluruh outlet selama 3 tahun",
x = "Pendapatan Total (Rp)",
y = "Frekuensi"
) +
theme_minimal()
Histogram digunakan untuk melihat distribusi variabel kontinu, yaitu total pendapatan per transaksi. Grafik ini membantu memahami bagaimana penyebaran nilai transaksi pelanggan.
Dari grafik terlihat bahwa distribusi data cenderung right-skewed (miring ke kanan), di mana sebagian besar transaksi berada pada nilai menengah, sementara transaksi dengan nilai sangat tinggi jumlahnya relatif sedikit.
Hal ini menunjukkan bahwa pendapatan restoran didominasi oleh transaksi dengan nominal sedang, sedangkan transaksi besar hanya terjadi pada kondisi tertentu. Insight ini penting untuk strategi pricing dan promosi, misalnya dengan mendorong pembelian bundling untuk meningkatkan nilai transaksi.
Visualisasi time series digunakan untuk menganalisis data yang memiliki dimensi waktu, seperti tanggal atau periode tertentu. Tujuan utama dari visualisasi ini adalah untuk mengidentifikasi tren, pola musiman, dan fluktuasi dari waktu ke waktu.
Dalam analisis ini, digunakan line chart untuk melihat perkembangan jumlah transaksi dan pendapatan berdasarkan waktu, serta moving average untuk memperhalus data agar tren jangka panjang lebih terlihat jelas.
Pendekatan ini sangat penting dalam analisis bisnis karena dapat membantu dalam memahami dinamika penjualan, mengidentifikasi periode puncak, serta mendukung perencanaan strategi di masa mendatang.
Bagaimana tren penjualan selama 3 tahun? Di bulan apa penjualan menghasilkan pendapatan tertinggi? Apakah ada pola musiman?
# Agregasi per bulan
bulanan <- resto_data %>%
group_by(Tanggal) %>%
summarise(
Total_Pendapatan = sum(Total, na.rm = TRUE),
.groups = "drop"
) %>%
arrange(Tanggal)
# Hitung Moving Average
bulanan$MA3 <- rollmean(bulanan$Total_Pendapatan,
k = 3,
fill = NA,
align = "center")
ggplot(bulanan, aes(x = Tanggal)) +
geom_line(aes(y = Total_Pendapatan), color = "#e7ccb6", size = 1) +
geom_line(aes(y = MA3), color = "#c1460d", size = 1.3) +
geom_point(aes(y = Total_Pendapatan), color = "#eca129", size = 1.5) +
scale_x_date(date_labels = "%b %Y", date_breaks = "6 months") +
scale_y_continuous(labels = comma) +
labs(
title = "Tren Pendapatan Bulanan Restoran Ayam Serayu",
subtitle = "Garis merah: Moving Average (per 3 bulan)",
x = "Bulan",
y = "Pendapatan Total (Rp)",
) +
theme_minimal()
Visualisasi ini menggunakan line chart dengan moving average untuk melihat tren pendapatan bulanan restoran. Moving average digunakan untuk menghaluskan fluktuasi data sehingga pola tren jangka panjang lebih mudah terlihat.
Berdasarkan grafik, terlihat bahwa pendapatan restoran menunjukkan tren meningkat dari tahun ke tahun, meskipun terdapat fluktuasi pada beberapa periode. Moving average membantu memperjelas arah tren tersebut.
Temuan ini mengindikasikan adanya pertumbuhan bisnis yang positif. Selain itu, terdapat indikasi pola musiman pada beberapa bulan tertentu, yang dapat dimanfaatkan untuk strategi promosi atau peningkatan stok pada periode dengan permintaan tinggi.
Bagaimana pola pesanan berdasarkan jam? Apakah lonjakan pesanan tertinggi di sekitar jam makan siang (lunch rush)?
# Agregasi jumlah pesanan per kategori jam
jam_pesanan <- resto_data %>%
group_by(Jam) %>%
summarise(
Jumlah_Transaksi = n_distinct(ID.Struk),
.groups = "drop"
) %>%
# Urutkan jam sesuai urutan waktu
mutate(Jam = factor(Jam, levels = c("Pagi (00:00-10:59)", "Siang (11:00-14:59)", "Sore (15:00-17:59)", "Malam (18:00-23:59)")))
ggplot(jam_pesanan, aes(x = Jam, y = Jumlah_Transaksi, group = 1)) +
geom_line(color = "#ee7c1d", size = 1) +
geom_point(color = "#7f201c", size = 3) +
scale_y_continuous(labels = comma) +
labs(
title = "Pola Pesanan Berdasarkan Waktu dalam Sehari",
x = "Waktu",
y = "Jumlah Transaksi",
) +
theme_minimal()
Visualisasi ini menunjukkan pola jumlah transaksi berdasarkan
kategori waktu dalam sehari. Variabel yang digunakan adalah
Jam dan jumlah transaksi.
Dari grafik terlihat bahwa transaksi mencapai puncaknya pada waktu siang hari, yang mengindikasikan adanya fenomena lunch rush. Setelah itu, jumlah transaksi menurun pada sore dan malam hari.
Hal ini menunjukkan bahwa waktu makan siang merupakan periode paling sibuk. Oleh karena itu, restoran perlu memastikan kesiapan operasional pada jam tersebut, seperti jumlah staf dan ketersediaan menu.
Bagaimana pula pola pesanan berdasarkan hari? Apakah saat hari pekan menunjukkan pola tertinggi dibandingkan hari biasa?
# Agregasi jumlah pesanan per hari
hari_pesanan <- resto_data %>%
group_by(Hari) %>%
summarise(
Jumlah_Transaksi = n_distinct(ID.Struk),
.groups = "drop"
) %>%
# Urutkan hari Senin–Minggu
mutate(Hari = factor(Hari, levels = c("Senin", "Selasa", "Rabu", "Kamis", "Jumat", "Sabtu", "Minggu")))
ggplot(hari_pesanan, aes(x = Hari, y = Jumlah_Transaksi, group = 1)) +
geom_line(color = "#ee7c1d", size = 1) +
geom_point(color = "#7f201c", size = 3) +
scale_y_continuous(labels = comma) +
labs(
title = "Pola Pesanan Berdasarkan Hari dalam Seminggu",
x = "Hari",
y = "Jumlah Pesanan (transaksi)",
) +
theme_minimal()
Visualisasi ini menggambarkan pola transaksi berdasarkan hari dalam seminggu. Tujuannya adalah untuk melihat apakah terdapat perbedaan aktivitas antara hari kerja dan akhir pekan.
Berdasarkan grafik, terlihat bahwa jumlah transaksi meningkat signifikan pada akhir pekan (Sabtu dan Minggu) dibandingkan hari kerja.
Hal ini menunjukkan bahwa perilaku pelanggan cenderung lebih aktif melakukan pembelian pada akhir pekan. Insight ini dapat dimanfaatkan untuk strategi promosi khusus weekend atau penyesuaian kapasitas operasional.
Berdasarkan seluruh hasil analisis visualisasi data, dapat disimpulkan bahwa restoran mengalami pertumbuhan yang positif dengan tren pendapatan yang meningkat dari tahun ke tahun. Layanan dine-in menjadi pilihan utama pelanggan, sementara aktivitas transaksi paling tinggi terjadi pada waktu siang dan akhir pekan.
Selain itu, distribusi pendapatan menunjukkan bahwa sebagian besar transaksi berada pada kategori menengah, dengan sedikit transaksi bernilai tinggi. Hal ini membuka peluang bagi restoran untuk meningkatkan strategi penjualan, seperti bundling menu atau promosi tertentu.
Sebagai saran, restoran dapat memfokuskan strategi pada peningkatan pengalaman dine-in, optimalisasi layanan saat jam sibuk, serta pengembangan promosi berbasis waktu dan perilaku pelanggan. Ke depan, analisis lebih lanjut dapat dilakukan dengan pendekatan statistik inferensial untuk mendukung pengambilan keputusan yang lebih akurat.