# Memuat dataset
library(dplyr)
resto_data <- read.csv("C:\\Users\\arimb\\OneDrive\\Documents\\visualisasi data\\visualisasi data time seris kelp.3\\AyamSerayu_3Years_Transaction_Data.csv", sep = ";")
glimpse(resto_data)
## Rows: 626,311
## Columns: 15
## $ Tanggal...Waktu <chr> "2023-01-01 00:00:00", "2023-01-01 00:00:00", "2023-…
## $ ID.Struk <chr> "TRX-20230101-8589", "TRX-20230101-8589", "TRX-20230…
## $ Outlet <chr> "AYAM SERAYU - CABANG 2", "AYAM SERAYU - CABANG 2", …
## $ Tipe.Penjualan <chr> "Dine in", "Dine in", "Dine in", "Dine in", "Dine in…
## $ Kasir <chr> "Rina", "Rina", "Budi", "Budi", "Budi", "Budi", "Bud…
## $ Nama.Produk <chr> "Ayam Bakar Madu", "Air Mineral", "Cah Kangkung", "K…
## $ Kategori <chr> "Makanan", "Minuman", "Makanan", "Makanan", "Makanan…
## $ Jumlah.Produk <int> 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1…
## $ Harga.Produk <int> 31000, 5000, 12000, 19000, 20000, 29000, 31000, 5000…
## $ Penjualan.Kotor <int> 31000, 5000, 12000, 19000, 40000, 29000, 62000, 5000…
## $ Total <int> 36000, 36000, 162000, 162000, 162000, 162000, 162000…
## $ Metode.Pembayaran <chr> "Tunai", "QRIS", "QRIS", "Tunai", "Debit", "Tunai", …
## $ Status.Pembayaran <chr> "Success", "Success", "Success", "Success", "Success…
## $ Diskon <int> 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…
getwd()
## [1] "C:/Users/arimb/Downloads"
Untuk memudahkan interpretasi, beberapa variabel akan dimodifikasi sebagai berikut.
resto_data <- resto_data %>%
rename(
Waktu = Tanggal...Waktu,
Pesanan = ID.Struk,
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),
Bulan1 = format(Waktu, "%b %Y"),
Bulan2 = floor_date(Waktu, "month") %>% as.Date(),
Hari = wday(Waktu, label = TRUE, abbr = FALSE, locale = "id_ID"),
Jam = case_when(
hour(Waktu) >= 0 & hour(Waktu) <= 10 ~ "Pagi",
hour(Waktu) >= 11 & hour(Waktu) <= 14 ~ "Siang",
hour(Waktu) >= 15 & hour(Waktu) <= 18 ~ "Sore",
hour(Waktu) >= 19 & hour(Waktu) <= 23 ~ "Malam"
)
)
glimpse(resto_data)
## Rows: 626,311
## Columns: 19
## $ Waktu <dttm> 2023-01-01, 2023-01-01, 2023-01-01, 2023-01-01, 2023-01-01, …
## $ Pesanan <chr> "TRX-20230101-8589", "TRX-20230101-8589", "TRX-20230101-3069"…
## $ Outlet <chr> "AYAM SERAYU - CABANG 2", "AYAM SERAYU - CABANG 2", "AYAM SER…
## $ 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…
## $ Bulan1 <chr> "Jan 2023", "Jan 2023", "Jan 2023", "Jan 2023", "Jan 2023", "…
## $ Bulan2 <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", "Pagi", "Pagi", "Pagi", "Pagi", "Pagi", "Pagi", "Pagi…
datatable(head(resto_data, 100), options = list(pageLength = 5, autoWidth = TRUE))
Bagaimana tren penjualan selama 2 tahun? Di bulan apa penjualan menghasilkan pendapatan tertinggi?
# Agregasi total pendapatan per bulan (dari Total)
bulanan <- resto_data %>%
group_by(Bulan2) %>%
summarise(
Total_Pendapatan = sum(Total, na.rm = TRUE),
.groups = "drop"
) %>%
# Filter hanya Jan & Jul setiap tahun
filter(format(Bulan2, "%b") %in% c("Jan", "Jul"))
# Line chart dengan moving average
ggplot(bulanan, aes(x = Bulan2, y = Total_Pendapatan)) +
geom_line(color = "#2E86AB", size = 1) +
geom_point(color = "#E67E22", size = 2) +
geom_smooth(method = "loess", se = FALSE, color = "#A569BD", linetype = "dashed") +
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 = "Jan 2023 – Des 2025 | Moving average (dashed)",
x = "Bulan",
y = "Total Pendapatan (Rp)",
caption = "Sumber: Data Transaksi 2023–2025"
) +
theme_minimal()
…
Bagaimana tren perkembangan outlet diliat dari banyak pesanan selama 2 tahun? Apakah ada pola musiman?
# Agregasi jumlah transaksi per outlet per bulan
outlet_bulanan <- resto_data %>%
group_by(Bulan2, Outlet) %>%
summarise(
Jumlah_Pesanan = n_distinct(Pesanan),
.groups = "drop"
) %>%
# Filter hanya Jan & Jul setiap tahun
filter(format(Bulan2, "%b") %in% c("Jan", "Jul"))
ggplot(outlet_bulanan, aes(x = Bulan2, y = Jumlah_Pesanan, color = Outlet)) +
geom_line(size = 1) +
geom_point(size = 1.5) +
scale_x_date(date_labels = "%b %Y", date_breaks = "6 months") +
scale_y_continuous(labels = comma) +
scale_color_manual(values = c("#2E86AB", "#E67E22", "#A569BD")) +
labs(
title = "Perkembangan Jumlah Pesanan per Outlet",
subtitle = "Jan 2023 – Jan 2026 | Bandingkan pertumbuhan tiap cabang",
x = "Bulan",
y = "Jumlah Pesanan (transaksi)",
color = "Outlet",
caption = "Sumber: Data Transaksi 2023–2025"
) +
theme_minimal()
…
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_Pesanan = n_distinct(Pesanan),
.groups = "drop"
) %>%
# Urutkan jam sesuai urutan waktu
mutate(Jam = factor(Jam, levels = c("Pagi", "Siang", "Sore", "Malam")))
ggplot(jam_pesanan, aes(x = Jam, y = Jumlah_Pesanan, group = 1)) +
geom_line(color = "#2E86AB", size = 1) +
geom_point(color = "#E67E22", size = 3) +
scale_y_continuous(labels = comma) +
labs(
title = "Pola Pesanan Berdasarkan Waktu dalam Sehari",
subtitle = "Lonjakan tertinggi terjadi pada jam siang (11:00–14:59)",
x = "Kategori Waktu",
y = "Jumlah Pesanan (transaksi)",
caption = "Sumber: Data Transaksi 2023–2025"
) +
theme_minimal()
…
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_Pesanan = n_distinct(Pesanan),
.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_Pesanan, group = 1)) +
geom_line(color = "#2E86AB", size = 1) +
geom_point(color = "#E67E22", size = 3) +
scale_y_continuous(labels = comma) +
labs(
title = "Pola Pesanan Berdasarkan Hari dalam Seminggu",
subtitle = "Akhir pekan (Sabtu–Minggu) menunjukkan lonjakan pesanan",
x = "Hari",
y = "Jumlah Pesanan (transaksi)",
caption = "Sumber: Data Transaksi 2023–2025"
) +
theme_minimal()
> Pertanyaan:
> Bagaimana distribusi layanan yang dipilih para pelanggan tiap
outlet? > Bagaimana distribusi jumlah kasir tiap layanan? - grouped
bar chart LAYANAN & KASIR
# Agregasi jumlah transaksi berdasarkan outlet & layanan
layanan_outlet <- resto_data %>%
group_by(Outlet, Layanan) %>%
summarise(
Jumlah = n(),
.groups = "drop"
) %>%
group_by(Outlet) %>%
mutate(
Proporsi = Jumlah / sum(Jumlah)
)
# Plot proportional bar chart
ggplot(layanan_outlet, aes(x = Outlet, y = Proporsi, fill = Layanan)) +
geom_bar(stat = "identity", position = "fill") +
scale_y_continuous(labels = percent) +
labs(
title = "Distribusi Layanan pada Setiap Outlet",
subtitle = "Perbandingan proporsi layanan (Dine-in, Take Away, dll)",
x = "Outlet",
y = "Proporsi",
fill = "Jenis Layanan",
caption = "Sumber: Data Transaksi 2023–2025"
) +
theme_minimal()
Distribusi layanan pada setiap outlet menunjukkan perbedaan preferensi
pelanggan dalam memilih jenis layanan. Outlet dengan dominasi layanan
tertentu mencerminkan kecenderungan perilaku pelanggan di lokasi
tersebut. Faktor lokasi, karakteristik pelanggan, dan fasilitas outlet
memengaruhi perbedaan ini. Informasi ini dapat digunakan untuk
mengoptimalkan strategi operasional dan pelayanan di masing-masing
outlet.
# Hitung total item per transaksi
jumlah_transaksi <- resto_data %>%
group_by(Pesanan) %>%
summarise(
Total_Item = sum(Jumlah, na.rm = TRUE),
.groups = "drop"
)
# Histogram distribusi
ggplot(jumlah_transaksi, aes(x = Total_Item)) +
geom_histogram(bins = 20, fill = "#2E86AB", color = "white") +
labs(
title = "Distribusi Jumlah Produk per Transaksi",
subtitle = "Melihat pola pembelian pelanggan",
x = "Jumlah Produk",
y = "Frekuensi",
caption = "Sumber: Data Transaksi 2023–2025"
) +
theme_minimal()
Distribusi jumlah produk per transaksi menunjukkan bahwa sebagian besar
pelanggan membeli dalam jumlah sedikit hingga sedang, dengan beberapa
transaksi besar sebagai outlier. Hal ini mencerminkan pola pembelian
individu yang dominan, serta peluang peningkatan penjualan melalui
strategi bundling atau paket promosi.
Distribusi Jumlah Produk per Transaksi Menggunakan Boxplot
ggplot(jumlah_transaksi, aes(y = Total_Item)) +
geom_boxplot(fill = "#E67E22") +
labs(
title = "Boxplot Jumlah Produk per Transaksi",
y = "Jumlah Produk"
) +
theme_minimal()
Boxplot menunjukkan bahwa sebagian besar pelanggan membeli dalam jumlah
produk yang relatif sedikit, dengan beberapa transaksi besar sebagai
outlier. Hal ini mencerminkan pola pembelian individu yang dominan.