Praktikum Week-4 berfokus pada penerapan Sintaks dan Kontrol Alur dalam pemrograman R untuk Data Science. Studi kasus menggunakan Dataset Penjualan Toko Retail yang terdiri dari 6 produk dalam 3 kategori (Elektronik, Fashion, Makanan & Minuman). Dua kompetensi utama yang dikembangkan:
if, if-else, if-else if-else, bersarang) untuk mengklasifikasikan produk dan menerapkan aturan bisnis penetapan harga.for, while, break, next) untuk memproses seluruh data transaksi secara iteratif dan menghasilkan laporan otomatis.Dataset mencatat 6 transaksi produk pada sebuah toko retail. Setiap produk memiliki: nama, kategori, harga satuan dalam Rupiah penuh, jumlah terjual, dan nama staf penjualan. Pendapatan dihitung sebagai harga × jumlah_terjual. Aturan bisnis yang diimplementasikan melalui kontrol alur meliputi:
Dataset retail berisi 6 record produk dari 3 kategori. Semua harga dalam Rupiah penuh (bukan ribuan), sehingga pendapatan = harga × jumlah_terjual menghasilkan nilai dalam skala jutaan Rupiah — sepenuhnya konsisten dengan semua logika ambang batas pada bagian selanjutnya.
# ============================================================
# 2.1 Membuat Dataset Penjualan Retail (harga dalam Rupiah penuh)
# ============================================================
sales <- data.frame(
produk = c("Laptop", "T-Shirt", "Mie Instan", "Smartphone", "Jeans", "Teh Hijau"),
kategori = c("Elektronik", "Fashion", "Mak & Min", "Elektronik", "Fashion", "Mak & Min"),
harga = c(12500000, 150000, 25000, 8000000, 350000, 45000), # Rupiah penuh
jml_terjual = c(3, 20, 150, 5, 30, 200),
staf = c("Andi", "Bela", "Citra", "Andi", "Doni", "Citra"),
stringsAsFactors = FALSE
)
# Variabel turunan: total pendapatan per produk
sales$pendapatan <- sales$harga * sales$jml_terjual
print(sales) produk kategori harga jml_terjual staf pendapatan
1 Laptop Elektronik 12500000 3 Andi 37500000
2 T-Shirt Fashion 150000 20 Bela 3000000
3 Mie Instan Mak & Min 25000 150 Citra 3750000
4 Smartphone Elektronik 8000000 5 Andi 40000000
5 Jeans Fashion 350000 30 Doni 10500000
6 Teh Hijau Mak & Min 45000 200 Citra 9000000
Pernyataan kondisional mengeksekusi blok kode yang berbeda berdasarkan kondisi logis yang dievaluasi. R mendukung tiga bentuk utama yang digunakan dalam praktikum ini:
if (kondisi) { ... } — dieksekusi hanya saat kondisi bernilai TRUEif (...) else { ... } — menangani hasil TRUE dan FALSE (keputusan biner)if (...) else if (...) else { ... } — menangani beberapa cabang yang saling eksklusifKondisional bersarang menempatkan if bagian dalam di dalam blok if bagian luar, memungkinkan logika keputusan berlapis.
Gunakan struktur if-else if-else untuk mengklasifikasikan tarif diskon setiap produk berdasarkan harga satuannya. Aturan bisnis:
# ============================================================
# 3.1 if-else if-else: Klasifikasi Tier Diskon Tiga Level
# ============================================================
for (i in 1:nrow(sales)) {
produk <- sales$produk[i]
harga <- sales$harga[i]
# Tiga cabang klasifikasi tier diskon
if (harga >= 5000000) {
tier <- "Premium"
pct_disc <- 0.15
} else if (harga >= 100000) {
tier <- "Menengah"
pct_disc <- 0.10
} else {
tier <- "Ekonomi"
pct_disc <- 0.05
}
nominal_disc <- as.integer(harga * pct_disc)
cat(sprintf("Produk: %-12s | Harga: %12s | Tier: %-9s | Diskon: %.0f%% (-%s)\n",
produk,
format(harga, big.mark = "."),
tier,
pct_disc * 100,
format(nominal_disc, big.mark = ".")))
}Produk: Laptop | Harga: 12.500.000 | Tier: Premium | Diskon: 15% (-1.875.000)
Produk: T-Shirt | Harga: 150.000 | Tier: Menengah | Diskon: 10% (-15.000)
Produk: Mie Instan | Harga: 25.000 | Tier: Ekonomi | Diskon: 5% (-1.250)
Produk: Smartphone | Harga: 8e+06 | Tier: Premium | Diskon: 15% (-1.200.000)
Produk: Jeans | Harga: 350.000 | Tier: Menengah | Diskon: 10% (-35.000)
Produk: Teh Hijau | Harga: 45.000 | Tier: Ekonomi | Diskon: 5% (-2.250)
if-else if-else mengevaluasi tiga bracket harga yang saling eksklusif secara berurutan, memastikan hanya satu cabang yang dieksekusi per produk. Laptop (Rp 12.500.000) dan Smartphone (Rp 8.000.000) masuk tier Premium dengan tarif 15%, menghasilkan nominal diskon masing-masing Rp 1.875.000 dan Rp 1.200.000 — insentif finansial yang cukup besar untuk mendorong keputusan pembelian bernilai tinggi. T-Shirt dan Jeans berada di tier Menengah (10%) dengan diskon yang lebih kecil, yakni Rp 15.000 dan Rp 35.000. Mie Instan dan Teh Hijau berada di tier Ekonomi (5%) dengan diskon nominal yang sangat kecil — Rp 1.250 dan Rp 2.250 — nyaris tidak berdampak bagi pembeli. Hal ini mengungkap wawasan struktural penetapan harga: tarif persentase yang identik menghasilkan dampak moneter yang sangat berbeda tergantung pada tier harga dasar produk.
Gunakan if-else sederhana untuk menetapkan label kinerja biner pada setiap produk berdasarkan total pendapatan. Ambang batas: pendapatan ≥ Rp 10.000.000 → "PENDAPATAN TINGGI", selainnya "Pendapatan Standar".
# ============================================================
# 3.2 if-else: Label Kinerja Pendapatan Biner
# ============================================================
cat("Label Kinerja Pendapatan\n")Label Kinerja Pendapatan
--------------------------------------------------------------------
for (i in 1:nrow(sales)) {
produk <- sales$produk[i]
pendapatan <- sales$pendapatan[i]
if (pendapatan >= 10000000) {
label <- "PENDAPATAN TINGGI"
flag <- "(**)"
} else {
label <- "Pendapatan Standar"
flag <- " "
}
cat(sprintf("%s %-12s | Pendapatan: %14s IDR | %s\n",
flag, produk,
format(pendapatan, big.mark = "."),
label))
}(**) Laptop | Pendapatan: 37.500.000 IDR | PENDAPATAN TINGGI
T-Shirt | Pendapatan: 3e+06 IDR | Pendapatan Standar
Mie Instan | Pendapatan: 3.750.000 IDR | Pendapatan Standar
(**) Smartphone | Pendapatan: 4e+07 IDR | PENDAPATAN TINGGI
(**) Jeans | Pendapatan: 10.500.000 IDR | PENDAPATAN TINGGI
Teh Hijau | Pendapatan: 9e+06 IDR | Pendapatan Standar
if-else biner dengan satu ambang batas adalah pilihan paling tepat ketika hanya dibutuhkan dua kategori hasil.
Gunakan if-else bersarang untuk menerapkan klasifikasi dua lapis pada setiap produk:
# ============================================================
# 3.3 if-else Bersarang: Tier Pendapatan + Peringatan Performa
# ============================================================
cat("Laporan Tier Pendapatan Tiga Level dengan Peringatan Bersarang\n")Laporan Tier Pendapatan Tiga Level dengan Peringatan Bersarang
========================================================================
for (i in 1:nrow(sales)) {
produk <- sales$produk[i]
pendapatan <- sales$pendapatan[i]
staf_nama <- sales$staf[i]
# Luar: klasifikasi tiga tier pendapatan
if (pendapatan >= 10000000) {
tier_pend <- "Pendapatan Tinggi"
# Dalam: flag performa terbaik — hanya dievaluasi untuk Pendapatan Tinggi
if (staf_nama == "Andi") {
peringatan <- "[Peringatan Performa Terbaik]"
} else {
peringatan <- ""
}
} else if (pendapatan >= 3000000) {
tier_pend <- "Pendapatan Sedang"
peringatan <- ""
} else {
tier_pend <- "Pendapatan Rendah"
peringatan <- ""
}
cat(sprintf("%-12s | Staf: %-6s | Pendapatan: %14s | %-18s %s\n",
produk,
staf_nama,
format(pendapatan, big.mark = "."),
tier_pend,
peringatan))
}Laptop | Staf: Andi | Pendapatan: 37.500.000 | Pendapatan Tinggi [Peringatan Performa Terbaik]
T-Shirt | Staf: Bela | Pendapatan: 3e+06 | Pendapatan Sedang
Mie Instan | Staf: Citra | Pendapatan: 3.750.000 | Pendapatan Sedang
Smartphone | Staf: Andi | Pendapatan: 4e+07 | Pendapatan Tinggi [Peringatan Performa Terbaik]
Jeans | Staf: Doni | Pendapatan: 10.500.000 | Pendapatan Tinggi
Teh Hijau | Staf: Citra | Pendapatan: 9e+06 | Pendapatan Sedang
if-else bersarang mengaktifkan lapisan keputusan bagian dalam secara eksklusif di dalam cabang Pendapatan Tinggi bagian luar — mengilustrasikan prinsip efisiensi penting: kondisi bagian dalam tidak pernah dievaluasi untuk produk Pendapatan Sedang atau Rendah, menghemat komputasi. Klasifikasi luar menghasilkan: Pendapatan Tinggi — Laptop, Smartphone, Jeans; Pendapatan Sedang — T-Shirt, Mie Instan, Teh Hijau; Pendapatan Rendah — tidak ada dalam dataset ini (semua produk melebihi Rp 3.000.000). Pemeriksaan bagian dalam mengidentifikasi staf Andi sebagai pengelola Laptop dan Smartphone — dua produk berpendapatan tertinggi — memicu [Peringatan Performa Terbaik] untuk keduanya. Jeans (Pendapatan Tinggi) dikelola oleh Doni sehingga tidak memicu peringatan. Pola bersarang ini memodelkan logika bisnis multi-kriteria yang umum digunakan dalam sistem CRM untuk mengidentifikasi dan memberikan penghargaan kepada manajer akun berprestasi terbaik.
Perulangan mengotomatiskan pemrosesan record demi record tanpa menduplikasi kode. R menyediakan dua struktur perulangan utama untuk praktikum ini:
for loop — digunakan saat jumlah iterasi diketahui (6 produk dalam dataset)while loop — digunakan saat kondisi berhenti bergantung pada nilai yang berubah secara dinamis saat runtimeKedua jenis perulangan mendukung break (keluar dari seluruh perulangan seketika) dan next (lewati iterasi saat ini dan lanjutkan ke berikutnya).
Gunakan for loop untuk mengidentifikasi dan mendaftarkan semua produk yang total pendapatannya melebihi Rp 5.000.000. Tampilkan setiap produk yang memenuhi syarat dengan nomor urut, dan cetak ringkasan jumlah di akhir.
# ============================================================
# 4.1 For Loop: Filter Produk dengan Pendapatan > Rp 5.000.000
# ============================================================
jumlah <- 0
for (i in 1:nrow(sales)) {
if (sales$pendapatan[i] > 5000000) {
jumlah <- jumlah + 1
cat(sprintf("[%d] %-12s | Pendapatan: %14s IDR\n",
jumlah,
sales$produk[i],
format(sales$pendapatan[i], big.mark = ".")))
}
}[1] Laptop | Pendapatan: 37.500.000 IDR
[2] Smartphone | Pendapatan: 4e+07 IDR
[3] Jeans | Pendapatan: 10.500.000 IDR
[4] Teh Hijau | Pendapatan: 9e+06 IDR
Total produk dengan pendapatan di atas Rp 5.000.000: 4 produk
if yang tertanam di dalam for loop bertindak sebagai gerbang filter yang hanya memicu penambahan penghitung dan output untuk baris yang memenuhi syarat. Variabel tambahan jumlah terakumulasi di setiap iterasi dan memberikan ringkasan agregat di akhir — teknik umum untuk menghasilkan laporan inventaris yang difilter.
Gunakan while loop untuk mengakumulasi total pendapatan toko produk demi produk (sesuai urutan dataset) hingga target penjualan harian Rp 50.000.000 tercapai atau terlampaui. Tampilkan progres di setiap langkah beserta jarak tersisa menuju target.
# ============================================================
# 4.2 While Loop: Akumulasi Pendapatan Hingga Target Rp 50.000.000
# ============================================================
target_harian <- 50000000
pend_kumulatif <- 0
indeks <- 1
cat(sprintf("Target Pendapatan Harian : Rp %s\n\n", format(target_harian, big.mark = ".")))Target Pendapatan Harian : Rp 5e+07
while (indeks <= nrow(sales) && pend_kumulatif < target_harian) {
produk <- sales$produk[indeks]
pend <- sales$pendapatan[indeks]
pend_kumulatif <- pend_kumulatif + pend
if (pend_kumulatif >= target_harian) {
cat(sprintf("Produk: %-12s | Pend: %12s | Kumulatif: %12s --> TARGET TERCAPAI!\n",
produk,
format(pend, big.mark = "."),
format(pend_kumulatif, big.mark = ".")))
break
} else {
tersisa <- target_harian - pend_kumulatif
cat(sprintf("Produk: %-12s | Pend: %12s | Kumulatif: %12s (-%s tersisa)\n",
produk,
format(pend, big.mark = "."),
format(pend_kumulatif, big.mark = "."),
format(tersisa, big.mark = ".")))
}
indeks <- indeks + 1
}Produk: Laptop | Pend: 37.500.000 | Kumulatif: 37.500.000 (-12.500.000 tersisa)
Produk: T-Shirt | Pend: 3e+06 | Kumulatif: 40.500.000 (-9.500.000 tersisa)
Produk: Mie Instan | Pend: 3.750.000 | Kumulatif: 44.250.000 (-5.750.000 tersisa)
Produk: Smartphone | Pend: 4e+07 | Kumulatif: 84.250.000 --> TARGET TERCAPAI!
cat(sprintf("\nKesimpulan: Target harian tercapai setelah memproses '%s' (indeks %d).\n",
sales$produk[indeks], indeks))
Kesimpulan: Target harian tercapai setelah memproses 'Smartphone' (indeks 4).
while loop memerlukan manajemen indeks secara manual — variabel indeks harus diinisialisasi sebelum perulangan dan ditambah di setiap iterasi. Kondisi gabungan menggunakan && (short-circuit AND) untuk mencegah overflow indeks ketika semua record sudah habis. Setelah menambahkan Laptop (37,5 juta), T-Shirt (3 juta), dan Mie Instan (3,75 juta), total kumulatif adalah Rp 44.250.000 — masih Rp 5.750.000 kurang dari target. Ketika Smartphone (Rp 40.000.000) ditambahkan pada indeks ke-4, kumulatif melonjak ke Rp 84.250.000 sehingga melampaui target Rp 50.000.000, dan break keluar dari perulangan dengan bersih. Perulangan tidak pernah memproses Jeans atau Teh Hijau (indeks 5–6), menunjukkan bahwa break menghindari komputasi yang tidak perlu. Pola ini secara langsung memodelkan dashboard POS (Point-of-Sale) real-time yang memantau produk mana yang "melewati garis target" untuk pelacakan pendapatan harian.
Gunakan break untuk menghentikan perulangan begitu produk "Mak & Min" pertama dengan pendapatan melebihi Rp 5.000.000 ditemukan. Cetak semua produk yang sudah diperiksa sebelum berhenti.
# ============================================================
# 4.3 For Loop dengan Break: Berhenti pada Produk Mak & Min Pertama
# ============================================================
cat("Mencari produk Mak & Min pertama dengan pendapatan > Rp 5.000.000...\n\n")Mencari produk Mak & Min pertama dengan pendapatan > Rp 5.000.000...
for (i in 1:nrow(sales)) {
produk <- sales$produk[i]
kategori <- sales$kategori[i]
pendapatan <- sales$pendapatan[i]
if (kategori == "Mak & Min" && pendapatan > 5000000) {
cat(sprintf(">> BERHENTI: '%s' (Mak & Min, Rp %s) — kondisi terpenuhi, perulangan dihentikan.\n",
produk, format(pendapatan, big.mark = ".")))
break
}
cat(sprintf("Diperiksa: %-12s | Kategori: %-11s | Pendapatan: Rp %s\n",
produk, kategori, format(pendapatan, big.mark = ".")))
}Diperiksa: Laptop | Kategori: Elektronik | Pendapatan: Rp 37.500.000
Diperiksa: T-Shirt | Kategori: Fashion | Pendapatan: Rp 3e+06
Diperiksa: Mie Instan | Kategori: Mak & Min | Pendapatan: Rp 3.750.000
Diperiksa: Smartphone | Kategori: Elektronik | Pendapatan: Rp 4e+07
Diperiksa: Jeans | Kategori: Fashion | Pendapatan: Rp 10.500.000
>> BERHENTI: 'Teh Hijau' (Mak & Min, Rp 9e+06) — kondisi terpenuhi, perulangan dihentikan.
Perulangan berhenti pada indeks baris: 6
kategori == "Mak & Min" && pendapatan > 5000000) mengharuskan kedua kondisi bernilai TRUE secara bersamaan. Dari dua produk Mak & Min, Mie Instan (indeks 3) ditemukan lebih dulu — pendapatannya Rp 3.750.000 memenuhi pemeriksaan kategori tetapi gagal pada ambang batas pendapatan, sehingga pemindaian berlanjut. Teh Hijau (indeks 6, Rp 9.000.000) memenuhi kedua kondisi, memicu break dan mengakhiri perulangan secara permanen pada indeks 6. Seluruh 5 produk sebelumnya dicetak secara normal. Perulangan tidak pernah mencoba memproses indeks hipotetis ke-7, karena break keluar sebelum iterasi lebih lanjut. Perbedaan konsep kunci: break keluar dari seluruh perulangan, sedangkan next hanya akan melewati satu iterasi dan membiarkan perulangan berlanjut.
Gunakan next untuk melewati semua produk kategori "Fashion" sambil tetap memproses semua produk Elektronik dan Mak & Min secara normal. Catat nama produk yang dilewati dalam sebuah vektor sebagai log audit.
# ============================================================
# 4.4 For Loop dengan Next: Lewati Semua Produk Kategori Fashion
# ============================================================
produk_dilewati <- c()
for (i in 1:nrow(sales)) {
produk <- sales$produk[i]
kategori <- sales$kategori[i]
pendapatan <- sales$pendapatan[i]
if (kategori == "Fashion") {
produk_dilewati <- c(produk_dilewati, produk)
cat(sprintf("(%s dilewati — kategori Fashion)\n", produk))
next
}
cat(sprintf("Produk: %-12s | Kategori: %-11s | Pendapatan: Rp %s\n",
produk, kategori, format(pendapatan, big.mark = ".")))
}Produk: Laptop | Kategori: Elektronik | Pendapatan: Rp 37.500.000
(T-Shirt dilewati — kategori Fashion)
Produk: Mie Instan | Kategori: Mak & Min | Pendapatan: Rp 3.750.000
Produk: Smartphone | Kategori: Elektronik | Pendapatan: Rp 4e+07
(Jeans dilewati — kategori Fashion)
Produk: Teh Hijau | Kategori: Mak & Min | Pendapatan: Rp 9e+06
cat(sprintf("\nTotal dilewati: %d (%s)\n",
length(produk_dilewati),
paste(produk_dilewati, collapse = ", ")))
Total dilewati: 2 (T-Shirt, Jeans)
next dipicu saat kategori == "Fashion" bernilai TRUE, langsung melompat ke iterasi loop berikutnya tanpa mengeksekusi baris cat() di bawahnya. Baik T-Shirt (indeks 2) maupun Jeans (indeks 5) dilewati, sementara semua produk Elektronik dan Mak & Min diproses secara normal. Yang krusial, perulangan tetap menyelesaikan seluruh 6 iterasi — perbedaan utama dengan break (yang akan menghentikan perulangan di indeks 2 pada produk Fashion pertama). Vektor produk_dilewati mengumpulkan nama yang dilewati di setiap iterasi dan memberikan jejak audit lengkap di akhir, mengonfirmasi bahwa tepat 2 record dikecualikan. Pola pencatatan audit ini merupakan praktik terbaik dalam pipeline data produksi di mana pengecualian data harus didokumentasikan untuk kepatuhan dan pelaporan hilir.
Buat laporan penjualan otomatis per produk yang menggabungkan semua struktur kondisional dalam satu kali lewat for loop. Untuk setiap produk, empat blok kondisional independen berjalan secara paralel: tier diskon, kategori pendapatan tiga tier, bendera stok, dan rekomendasi strategis yang diturunkan dari kondisi gabungan menggunakan output blok-blok sebelumnya.
# ============================================================
# 5.1 Laporan Penjualan Otomatis: 4 Blok Kondisional + For Loop
# ============================================================
cat("================================================================\n")================================================================
TOKO RETAIL — LAPORAN ANALISIS PENJUALAN OTOMATIS
================================================================
for (i in 1:nrow(sales)) {
produk <- sales$produk[i]
kategori <- sales$kategori[i]
harga <- sales$harga[i]
jml <- sales$jml_terjual[i]
pendapatan <- sales$pendapatan[i]
staf_nama <- sales$staf[i]
# --- Blok 1: Tier Diskon ---
if (harga >= 5000000) {
tier <- "Premium"
pct_disc <- 0.15
} else if (harga >= 100000) {
tier <- "Menengah"
pct_disc <- 0.10
} else {
tier <- "Ekonomi"
pct_disc <- 0.05
}
nominal_disc <- as.integer(harga * pct_disc)
# --- Blok 2: Kategori Pendapatan Tiga Tier ---
if (pendapatan >= 10000000) {
kat_pend <- "Pendapatan Tinggi"
} else if (pendapatan >= 3000000) {
kat_pend <- "Pendapatan Sedang"
} else {
kat_pend <- "Pendapatan Rendah"
}
# --- Blok 3: Bendera Stok ---
if (jml >= 100) {
bendera_stok <- "PESAN ULANG SEKARANG"
} else if (jml >= 20) {
bendera_stok <- "Pantau Stok"
} else {
bendera_stok <- "Stok Cukup"
}
# --- Blok 4: Rekomendasi Strategis (menggunakan output Blok 2 + 3) ---
if (kat_pend == "Pendapatan Tinggi" && tier == "Premium") {
rekomendasi <- "Pertahankan strategi — produk unggulan"
} else if (kat_pend == "Pendapatan Tinggi" && tier == "Menengah") {
rekomendasi <- "Pertimbangkan upsell — pendapatan kuat di harga menengah"
} else if (kat_pend == "Pendapatan Sedang" && bendera_stok == "PESAN ULANG SEKARANG") {
rekomendasi <- "Tinjau margin harga — volume tinggi, pendapatan sedang"
} else if (tier == "Ekonomi" && bendera_stok == "PESAN ULANG SEKARANG") {
rekomendasi <- "Promosi bundel — tingkatkan pendapatan tier Ekonomi"
} else {
rekomendasi <- "Pemantauan standar — tidak ada tindakan prioritas"
}
# --- Cetak Laporan Lengkap ---
cat(sprintf("[%d] %-12s | Kategori: %-11s | Staf: %s\n",
i, produk, kategori, staf_nama))
cat(sprintf(" Harga : Rp %s | Jml Terjual : %d unit\n",
format(harga, big.mark = "."), jml))
cat(sprintf(" Pendapatan : Rp %s (%s)\n",
format(pendapatan, big.mark = "."), kat_pend))
cat(sprintf(" Tier Diskon : %-9s | Nom. Diskon : Rp %s (%.0f%%)\n",
tier, format(nominal_disc, big.mark = "."), pct_disc * 100))
cat(sprintf(" Bendera Stok : %s\n", bendera_stok))
cat(sprintf(" Rekomendasi : %s\n\n", rekomendasi))
}[1] Laptop | Kategori: Elektronik | Staf: Andi
Harga : Rp 12.500.000 | Jml Terjual : 3 unit
Pendapatan : Rp 37.500.000 (Pendapatan Tinggi)
Tier Diskon : Premium | Nom. Diskon : Rp 1.875.000 (15%)
Bendera Stok : Stok Cukup
Rekomendasi : Pertahankan strategi — produk unggulan
[2] T-Shirt | Kategori: Fashion | Staf: Bela
Harga : Rp 150.000 | Jml Terjual : 20 unit
Pendapatan : Rp 3e+06 (Pendapatan Sedang)
Tier Diskon : Menengah | Nom. Diskon : Rp 15.000 (10%)
Bendera Stok : Pantau Stok
Rekomendasi : Pemantauan standar — tidak ada tindakan prioritas
[3] Mie Instan | Kategori: Mak & Min | Staf: Citra
Harga : Rp 25.000 | Jml Terjual : 150 unit
Pendapatan : Rp 3.750.000 (Pendapatan Sedang)
Tier Diskon : Ekonomi | Nom. Diskon : Rp 1.250 (5%)
Bendera Stok : PESAN ULANG SEKARANG
Rekomendasi : Tinjau margin harga — volume tinggi, pendapatan sedang
[4] Smartphone | Kategori: Elektronik | Staf: Andi
Harga : Rp 8e+06 | Jml Terjual : 5 unit
Pendapatan : Rp 4e+07 (Pendapatan Tinggi)
Tier Diskon : Premium | Nom. Diskon : Rp 1.200.000 (15%)
Bendera Stok : Stok Cukup
Rekomendasi : Pertahankan strategi — produk unggulan
[5] Jeans | Kategori: Fashion | Staf: Doni
Harga : Rp 350.000 | Jml Terjual : 30 unit
Pendapatan : Rp 10.500.000 (Pendapatan Tinggi)
Tier Diskon : Menengah | Nom. Diskon : Rp 35.000 (10%)
Bendera Stok : Pantau Stok
Rekomendasi : Pertimbangkan upsell — pendapatan kuat di harga menengah
[6] Teh Hijau | Kategori: Mak & Min | Staf: Citra
Harga : Rp 45.000 | Jml Terjual : 200 unit
Pendapatan : Rp 9e+06 (Pendapatan Sedang)
Tier Diskon : Ekonomi | Nom. Diskon : Rp 2.250 (5%)
Bendera Stok : PESAN ULANG SEKARANG
Rekomendasi : Tinjau margin harga — volume tinggi, pendapatan sedang
Simulasikan pendapatan T-Shirt yang tumbuh 15% per bulan melalui while loop, dimulai dari Rp 3.000.000, hingga sub-target kategori Fashion sebesar Rp 20.000.000 tercapai. Tampilkan trajektori pendapatan dan jarak tersisa di setiap langkah.
# ============================================================
# 5.2 While Loop: Simulasi Pertumbuhan Majemuk Pendapatan T-Shirt
# ============================================================
pend_saat_ini <- sales$pendapatan[sales$produk == "T-Shirt"] # Rp 3.000.000
target_pend <- 20000000
bulan <- 0
laju_tumbuh <- 0.15
cat(sprintf("Produk : T-Shirt (Fashion)\n"))Produk : T-Shirt (Fashion)
Pendapatan Awal : Rp 3e+06
Target Pendapatan: Rp 2e+07
Pertumbuhan/Bulan: 15%
while (pend_saat_ini < target_pend) {
bulan <- bulan + 1
pend_saat_ini <- pend_saat_ini * (1 + laju_tumbuh)
if (pend_saat_ini >= target_pend) {
cat(sprintf("Bulan %2d: Rp %12.0f --> TARGET TERCAPAI!\n",
bulan, pend_saat_ini))
} else {
tersisa <- target_pend - pend_saat_ini
cat(sprintf("Bulan %2d: Rp %12.0f (Rp %s masih dibutuhkan)\n",
bulan, pend_saat_ini,
format(round(tersisa), big.mark = ".")))
}
}Bulan 1: Rp 3450000 (Rp 16.550.000 masih dibutuhkan)
Bulan 2: Rp 3967500 (Rp 16.032.500 masih dibutuhkan)
Bulan 3: Rp 4562625 (Rp 15.437.375 masih dibutuhkan)
Bulan 4: Rp 5247019 (Rp 14.752.981 masih dibutuhkan)
Bulan 5: Rp 6034072 (Rp 13.965.928 masih dibutuhkan)
Bulan 6: Rp 6939182 (Rp 13.060.818 masih dibutuhkan)
Bulan 7: Rp 7980060 (Rp 12.019.940 masih dibutuhkan)
Bulan 8: Rp 9177069 (Rp 10.822.931 masih dibutuhkan)
Bulan 9: Rp 10553629 (Rp 9.446.371 masih dibutuhkan)
Bulan 10: Rp 12136673 (Rp 7.863.327 masih dibutuhkan)
Bulan 11: Rp 13957174 (Rp 6.042.826 masih dibutuhkan)
Bulan 12: Rp 16050750 (Rp 3.949.250 masih dibutuhkan)
Bulan 13: Rp 18458363 (Rp 1.541.637 masih dibutuhkan)
Bulan 14: Rp 21227117 --> TARGET TERCAPAI!
cat(sprintf("\nKesimpulan: %d bulan dibutuhkan untuk mencapai target Rp %s.\n",
bulan, format(target_pend, big.mark = ".")))
Kesimpulan: 14 bulan dibutuhkan untuk mencapai target Rp 2e+07.
while loop adalah struktur yang tepat karena jumlah bulan yang tepat (14) tidak dapat diketahui sebelum eksekusi — ditentukan secara dinamis oleh aritmatika pemajemukan. if-else bersarang di dalam loop membedakan bulan yang masih berlangsung dengan bulan pencapaian akhir. Akselerasi pertumbuhan terlihat jelas: kenaikan Bulan ke-1 hanya Rp 450.000, sementara kenaikan Bulan ke-14 melebihi Rp 2.700.000 — tarif 15% yang sama diterapkan pada basis yang jauh lebih besar. Pola eksponensial ini menjelaskan mengapa pertumbuhan majemuk, meskipun dengan tarif sedang, menjadi sangat kuat seiring waktu dan merupakan model standar dalam perkiraan pendapatan retail dan perencanaan keuangan.
Lima jenis grafik dihasilkan di bawah ini, masing-masing terhubung langsung ke bagian tertentu dari logika kontrol alur praktikum:
Visualisasikan total pendapatan untuk 6 produk sebagai diagram batang horizontal yang diurutkan dari tertinggi ke terendah, dengan label nilai Rupiah pada setiap batang. Subjudul mereferensikan ambang batas Rp 5.000.000 dari Bagian 4.1.
# ============================================================
# 6.1 Diagram Batang Horizontal: Total Pendapatan per Produk
# ============================================================
library(ggplot2)
library(dplyr)
library(scales)
prod_diurutkan <- sales %>%
arrange(desc(pendapatan)) %>%
mutate(produk = factor(produk, levels = produk))
ggplot(prod_diurutkan, aes(x = produk, y = pendapatan, fill = pendapatan)) +
geom_col(width = 0.65, show.legend = FALSE) +
geom_text(aes(label = paste0("Rp ", format(pendapatan, big.mark = "."))),
hjust = -0.08, fontface = "bold", size = 3.8, color = "#1A237E") +
scale_fill_gradient(low = "#9FA8DA", high = "#283593") +
scale_y_continuous(expand = expansion(mult = c(0, 0.26)), labels = comma) +
coord_flip() +
labs(
title = "Total Pendapatan per Produk",
subtitle = "Diurutkan tertinggi ke terendah | Ambang Rp 5.000.000 (Bag. 4.1): 4 produk memenuhi syarat",
x = "Produk",
y = "Total Pendapatan (IDR)",
caption = "Sumber: Dataset Penjualan Toko Retail — Praktikum Week-4 | NENY"
) +
theme_minimal(base_size = 13) +
theme(
plot.title = element_text(face = "bold", size = 16, color = "#283593"),
plot.subtitle = element_text(color = "#5C6BC0", size = 10.5),
axis.text = element_text(face = "bold", color = "#1A1A2E", size = 11),
panel.grid.major.y = element_blank(),
panel.grid.minor = element_blank(),
plot.background = element_rect(fill = "#F4F6FF", color = NA),
panel.background = element_rect(fill = "#F4F6FF", color = NA),
plot.caption = element_text(color = "#888888", size = 9),
plot.margin = margin(12, 20, 12, 12)
)Tampilkan harga satuan setiap produk bersama nominal diskon yang dihitung (dikelompokkan per tier harga), secara langsung memvisualisasikan logika tiga cabang if-else if-else dari Bagian 3.1. Panel facet memisahkan ketiga tier untuk perbandingan yang jelas.
# ============================================================
# 6.2 Diagram Batang Berkelompok + Facet: Harga vs Diskon per Tier
# ============================================================
library(tidyr)
data_diskon <- sales %>%
mutate(
tier = case_when(
harga >= 5000000 ~ "Premium (15%)",
harga >= 100000 ~ "Menengah (10%)",
TRUE ~ "Ekonomi (5%)"
),
nominal_disc = as.integer(harga * case_when(
harga >= 5000000 ~ 0.15,
harga >= 100000 ~ 0.10,
TRUE ~ 0.05
)),
tier = factor(tier, levels = c("Premium (15%)", "Menengah (10%)", "Ekonomi (5%)"))
) %>%
select(produk, tier, harga, nominal_disc) %>%
pivot_longer(cols = c(harga, nominal_disc),
names_to = "jenis",
values_to = "jumlah") %>%
mutate(jenis = factor(jenis,
levels = c("harga", "nominal_disc"),
labels = c("Harga Satuan (IDR)", "Nominal Diskon (IDR)")))
pal_disc <- c("Harga Satuan (IDR)" = "#5C6BC0", "Nominal Diskon (IDR)" = "#E91E63")
ggplot(data_diskon, aes(x = produk, y = jumlah, fill = jenis)) +
geom_col(position = position_dodge(width = 0.72), width = 0.64) +
geom_text(aes(label = format(jumlah, big.mark = ".")),
position = position_dodge(width = 0.72),
vjust = -0.45, size = 2.9, fontface = "bold", color = "#1A237E") +
facet_wrap(~ tier, scales = "free", nrow = 1) +
scale_fill_manual(values = pal_disc) +
scale_y_continuous(labels = comma, expand = expansion(mult = c(0, 0.22))) +
labs(
title = "Harga Satuan vs Nominal Diskon per Tier Harga",
subtitle = "Premium ≥ Rp 5.000.000 (15%) | Menengah ≥ Rp 100.000 (10%) | Ekonomi < Rp 100.000 (5%)",
x = "Produk", y = "Jumlah (IDR)", fill = NULL,
caption = "Sumber: Dataset Penjualan Toko Retail — Praktikum Week-4 | NENY"
) +
theme_minimal(base_size = 11.5) +
theme(
plot.title = element_text(face = "bold", size = 14, color = "#4A148C"),
plot.subtitle = element_text(color = "#7B1FA2", size = 9.5),
strip.text = element_text(face = "bold", size = 11, color = "#283593",
margin = margin(b = 6)),
strip.background = element_rect(fill = "#E8EAF6", color = "#9FA8DA"),
legend.position = "top",
legend.text = element_text(size = 10),
panel.grid.minor = element_blank(),
plot.background = element_rect(fill = "#F4F6FF", color = NA),
panel.background = element_rect(fill = "#F4F6FF", color = NA),
plot.caption = element_text(color = "#888888", size = 9)
)Tampilkan proporsi total pendapatan toko yang dikontribusikan oleh setiap kategori produk — Elektronik, Fashion, dan Mak & Min — secara langsung mencerminkan klasifikasi tiga tier kategori dari Bagian 3.3.
# ============================================================
# 6.3 Diagram Lingkaran: Porsi Pendapatan per Kategori
# ============================================================
pend_kat <- sales %>%
group_by(kategori) %>%
summarise(total_pend = sum(pendapatan), .groups = "drop") %>%
arrange(desc(total_pend)) %>%
mutate(
pct = total_pend / sum(total_pend) * 100,
label_pie = paste0(kategori, "\n",
sprintf("%.1f%%", pct),
"\n(Rp ", format(total_pend, big.mark = "."), ")")
)
warna_kat <- c("Elektronik" = "#3949AB", "Fashion" = "#8E24AA", "Mak & Min" = "#00838F")
ggplot(pend_kat, aes(x = "", y = total_pend, fill = kategori)) +
geom_col(width = 1, color = "white", linewidth = 1.5) +
coord_polar(theta = "y", start = 0) +
geom_text(aes(label = label_pie),
position = position_stack(vjust = 0.5),
size = 4, fontface = "bold", color = "white", lineheight = 1.35) +
scale_fill_manual(values = warna_kat) +
labs(
title = "Porsi Pendapatan per Kategori Produk",
subtitle = "Elektronik vs Fashion vs Mak & Min — Total: Rp 103.750.000",
caption = "Sumber: Dataset Penjualan Toko Retail — Praktikum Week-4 | NENY"
) +
theme_void(base_size = 13) +
theme(
plot.title = element_text(face = "bold", size = 15, color = "#283593",
hjust = 0.5, margin = margin(b = 4)),
plot.subtitle = element_text(color = "#5C6BC0", size = 10.5, hjust = 0.5),
legend.position = "bottom",
legend.title = element_blank(),
legend.text = element_text(size = 11, face = "bold"),
plot.background = element_rect(fill = "#F4F6FF", color = NA),
plot.caption = element_text(color = "#888888", size = 9,
hjust = 0.5, margin = margin(t = 8))
)Visualisasikan simulasi pertumbuhan majemuk pendapatan T-Shirt dari Bagian 5.2 — trajektori 14 bulan dari Rp 3.000.000 menuju target Rp 20.000.000 — dengan area pertumbuhan yang diarsir, garis referensi target, dan anotasi tonggak pencapaian.
# ============================================================
# 6.4 Diagram Garis: Pertumbuhan T-Shirt (Simulasi Bagian 5.2)
# ============================================================
pend_awal <- sales$pendapatan[sales$produk == "T-Shirt"] # 3.000.000
target_pend <- 20000000
laju_tumbuh <- 0.15
# Rekonstruksi data frame simulasi
data_sim <- data.frame(bulan = 0, pendapatan = pend_awal, tercapai = FALSE)
pend_sim <- pend_awal
while (pend_sim < target_pend) {
pend_sim <- pend_sim * (1 + laju_tumbuh)
tercapai <- pend_sim >= target_pend
data_sim <- rbind(data_sim,
data.frame(bulan = nrow(data_sim),
pendapatan = pend_sim,
tercapai = tercapai))
}
jumlah_bulan <- max(data_sim$bulan)
ggplot(data_sim, aes(x = bulan, y = pendapatan)) +
geom_ribbon(aes(ymin = pend_awal, ymax = pendapatan),
fill = "#C5CAE9", alpha = 0.40) +
geom_hline(yintercept = target_pend, linetype = "dashed",
color = "#E53935", linewidth = 1.1) +
geom_line(color = "#5C6BC0", linewidth = 2.0) +
geom_point(size = 4.5, shape = 21, stroke = 1.5,
fill = ifelse(data_sim$tercapai, "#E53935", "#5C6BC0"),
color = "white") +
annotate("text", x = 1, y = target_pend + 950000,
label = paste0("Target: Rp ", format(target_pend, big.mark = ".")),
color = "#C62828", fontface = "bold", size = 3.8, hjust = 0) +
annotate("text", x = jumlah_bulan, y = max(data_sim$pendapatan) - 1300000,
label = paste0("Bulan ", jumlah_bulan,
"\nRp ", format(round(max(data_sim$pendapatan)), big.mark = ".")),
color = "#1A237E", fontface = "bold", size = 3.2, hjust = 0.5) +
scale_x_continuous(breaks = 0:jumlah_bulan) +
scale_y_continuous(labels = comma, expand = expansion(mult = c(0.05, 0.14))) +
labs(
title = "Pertumbuhan Pendapatan T-Shirt — Laju Majemuk 15%/Bulan",
subtitle = paste0("Mulai Rp 3.000.000 → mencapai target Rp 20.000.000 dalam ",
jumlah_bulan, " bulan (simulasi while loop)"),
x = "Bulan",
y = "Pendapatan (IDR)",
caption = "Sumber: Dataset Penjualan Toko Retail — Praktikum Week-4 | NENY"
) +
theme_minimal(base_size = 12) +
theme(
plot.title = element_text(face = "bold", size = 14, color = "#283593"),
plot.subtitle = element_text(color = "#5C6BC0", size = 10.5),
axis.text = element_text(color = "#1A1A2E"),
legend.position = "none",
panel.grid.minor = element_blank(),
plot.background = element_rect(fill = "#F4F6FF", color = NA),
panel.background = element_rect(fill = "#F4F6FF", color = NA),
plot.caption = element_text(color = "#888888", size = 9)
)while loop dari Bagian 5.2 menjadi nyata secara visual. Area bayangan menyoroti kumulatif pendapatan yang diperoleh selama 14 bulan simulasi. Bentuk kurva eksponensial yang khas terlihat jelas: garis hampir datar dari Bulan 0 hingga Bulan 5 (kenaikan absolut kecil pada basis yang kecil), kemudian membelok tajam ke atas mulai Bulan 10 (laju 15% yang sama kini beroperasi pada basis yang jauh lebih besar). Garis putus-putus merah sebagai target Rp 20.000.000 dan titik merah pada Bulan ke-14 menandai titik keluar simulasi yang ditentukan oleh while loop. Subjudul secara dinamis menampilkan jumlah bulan yang dihitung oleh loop, menghubungkan langsung visualisasi dengan kode. Perilaku eksponensial ini menunjukkan mengapa model pertumbuhan majemuk lebih disukai daripada proyeksi linier dalam perkiraan ritel: kenaikan pendapatan Bulan ke-1 adalah Rp 450.000, sementara kenaikan Bulan ke-14 mencapai sekitar Rp 2,77 juta — akselerasi 6× pada laju persentase yang sama.
Buat diagram sebar gelembung dengan sumbu X = harga satuan (skala logaritmik), sumbu Y = kuantitas terjual, ukuran gelembung = total pendapatan, dan warna = kategori produk. Grafik ini memberikan gambaran portofolio lengkap yang menunjukkan bagaimana harga, volume, dan pendapatan berinteraksi di ketiga kategori secara bersamaan.
# ============================================================
# 6.5 Diagram Sebar Gelembung: Harga vs Kuantitas vs Pendapatan
# ============================================================
data_sebar <- sales %>%
mutate(
tier = factor(
case_when(
harga >= 5000000 ~ "Premium",
harga >= 100000 ~ "Menengah",
TRUE ~ "Ekonomi"
),
levels = c("Ekonomi", "Menengah", "Premium")
)
)
warna_kat2 <- c("Elektronik" = "#3949AB", "Fashion" = "#8E24AA", "Mak & Min" = "#00838F")
ggplot(data_sebar, aes(x = harga, y = jml_terjual)) +
geom_smooth(method = "lm", se = TRUE, color = "#90A4AE",
fill = "#CFD8DC", linewidth = 1.1, alpha = 0.45) +
geom_point(aes(fill = kategori, size = pendapatan),
shape = 21, color = "white", stroke = 2.2, alpha = 0.92) +
geom_text(aes(label = produk),
vjust = -1.7, fontface = "bold", size = 3.7, color = "#1A237E") +
scale_fill_manual(values = warna_kat2) +
scale_size_continuous(
range = c(6, 17),
labels = comma,
name = "Pendapatan (IDR)"
) +
scale_x_log10(
labels = comma,
breaks = c(25000, 50000, 150000, 350000, 1000000, 5000000, 12500000)
) +
scale_y_continuous(labels = comma,
expand = expansion(mult = c(0.10, 0.24))) +
labs(
title = "Harga vs Kuantitas Terjual — Diagram Sebar Gelembung",
subtitle = "Ukuran gelembung = total pendapatan | Warna = kategori | Sumbu X: skala log",
x = "Harga Satuan (IDR, skala log)",
y = "Kuantitas Terjual (unit)",
fill = "Kategori",
caption = "Sumber: Dataset Penjualan Toko Retail — Praktikum Week-4 | NENY"
) +
theme_minimal(base_size = 12) +
theme(
plot.title = element_text(face = "bold", size = 14, color = "#283593"),
plot.subtitle = element_text(color = "#5C6BC0", size = 10),
axis.text = element_text(color = "#1A1A2E"),
legend.position = "right",
legend.title = element_text(size = 10, face = "bold"),
panel.grid.minor = element_blank(),
plot.background = element_rect(fill = "#F4F6FF", color = NA),
panel.background = element_rect(fill = "#F4F6FF", color = NA),
plot.caption = element_text(color = "#888888", size = 9)
)# ============================================================
# 7. Tabel Ringkasan: Konsep Kontrol Alur yang Diterapkan
# ============================================================
tabel_ringkasan <- data.frame(
Konsep = c(
"if / else if / else",
"for loop",
"while loop",
"break",
"next"
),
"Sintaks R" = c(
"if (kond) {} else if (kond) {} else {}",
"for (i in 1:n) { ... }",
"while (kondisi) { ... }",
"break",
"next"
),
"Penggunaan Terbaik" = c(
"Aturan bisnis multi-cabang dengan hasil yang saling eksklusif",
"Memproses semua record saat jumlah iterasi total diketahui",
"Iterasi hingga nilai yang terakumulasi secara dinamis memenuhi target",
"Keluar dari seluruh perulangan secara seketika dan permanen",
"Lewati record saat ini; lanjutkan memproses record yang tersisa"
),
"Penerapan dalam Praktikum" = c(
"Klasifikasi tier diskon tiga level berdasarkan harga satuan (Bag. 3.1)",
"Daftar produk dengan pendapatan > Rp 5.000.000 (Bag. 4.1)",
"Akumulasi pendapatan hingga target harian Rp 50.000.000 (Bag. 4.2)",
"Hentikan pemindaian pada produk Mak & Min pertama (Bag. 4.3)",
"Lewati produk Fashion; proses Elektronik & Mak & Min (Bag. 4.4)"
),
check.names = FALSE
)
print(tabel_ringkasan) Konsep Sintaks R
1 if / else if / else if (kond) {} else if (kond) {} else {}
2 for loop for (i in 1:n) { ... }
3 while loop while (kondisi) { ... }
4 break break
5 next next
Penggunaan Terbaik
1 Aturan bisnis multi-cabang dengan hasil yang saling eksklusif
2 Memproses semua record saat jumlah iterasi total diketahui
3 Iterasi hingga nilai yang terakumulasi secara dinamis memenuhi target
4 Keluar dari seluruh perulangan secara seketika dan permanen
5 Lewati record saat ini; lanjutkan memproses record yang tersisa
Penerapan dalam Praktikum
1 Klasifikasi tier diskon tiga level berdasarkan harga satuan (Bag. 3.1)
2 Daftar produk dengan pendapatan > Rp 5.000.000 (Bag. 4.1)
3 Akumulasi pendapatan hingga target harian Rp 50.000.000 (Bag. 4.2)
4 Hentikan pemindaian pada produk Mak & Min pertama (Bag. 4.3)
5 Lewati produk Fashion; proses Elektronik & Mak & Min (Bag. 4.4)
Praktikum Week-4 berhasil mendemonstrasikan pernyataan kondisional, struktur perulangan, dan visualisasi ggplot2 dalam R melalui studi kasus penjualan toko retail yang koheren. Enam kesimpulan utama ditetapkan:
next untuk melewati kategori (Bag. 4.4), dan menghasilkan laporan otomatis multi-blok komprehensif (Bag. 5.1) — semuanya dalam satu kali lewat per produk.break yang akan menghentikan perulangan sepenuhnya pada produk Fashion pertama.