Assigment Week 5 ~ Functions & Loops + Data Science
Chandra Rizal Alamsyah
Student Majoring in Data Science at ITSB
NIM: 52250068
Email: chandra240205@gmail.com
1 Pendahuluan
Laporan ini disusun untuk memenuhi tugas praktikum mata kuliah Data Science Programming di Institut Teknologi Sains Bandung (ITSB). Fokus utama dari praktikum ini adalah untuk mendemonstrasikan kemampuan dalam membangun alur kerja ilmu data yang terotomatisasi dengan menggunakan struktur pemrograman tingkat lanjut.
1.1 Tujuan Praktikum
Tujuan utama dari pengerjaan tugas ini adalah:
Pembangunan Fungsi Multi-Layer: Mampu menyusun fungsi yang kompleks dengan memanfaatkan nested loops (perulangan bertingkat) dan logika kondisional.
Simulasi Multi-Dataset: Mengelola dan memproses simulasi data dari berbagai sumber atau skenario secara bersamaan.
Statistik dan Visualisasi Lanjut: Melakukan transformasi data, perhitungan statistik tingkat lanjut, serta menyajikan informasi dalam bentuk visualisasi yang informatif.
Otomatisasi Workflow: Mengembangkan skrip yang dapat mengotomatisasi proses pengolahan data dari awal hingga menjadi laporan akhir.
1.2 Cakupan Tugas
Praktikum ini mencakup 8 modul tugas utama yang mensimulasikan tantangan nyata di dunia data science, mulai dari pembuatan rumus dinamis, simulasi penjualan dan diskon, analisis performa karyawan dan perusahaan, hingga metode simulasi Monte Carlo untuk perhitungan probabilitas.Seluruh tugas diimplementasikan menggunakan bahasa pemrograman R dengan hasil akhir berupa dokumen HTML interaktif.
2 Dynamic Multi-Formula Function
Analisis ini berfokus pada pembuatan fungsi kustom yang mampu menangani berbagai jenis perhitungan matematika secara dinamis. Dengan menggabungkan konsep Nested Loops dan Conditional Logic, sistem dapat memproses serangkaian data input (\(x\)) dan menghasilkan output (\(y\)) berdasarkan rumus yang dipilih oleh pengguna.
2.1 Visualisasi
# --- TUGAS 1: DYNAMIC MULTI-FORMULA FUNCTION ---
# 1. Load Library
library(plotly)
library(ggplot2)
library(tidyr)
# 2. Definisi Fungsi Utama dengan Nested Loops dan Kondisional
# Fungsi ini menghitung nilai y berdasarkan kategori rumus yang dipilih
compute_formula <- function(x_vector, formulas) {
# Inisialisasi data frame dengan kolom x
results <- data.frame(x = x_vector)
# Outer Loop: Mengiterasi setiap jenis formula (Linear, Quadratic, dll)
for (f in formulas) {
y_values <- numeric(length(x_vector)) # Wadah sementara untuk hasil perhitungan
# Inner Loop: Mengiterasi setiap angka dalam vektor x (1 sampai 20)
for (i in 1:length(x_vector)) {
x_val <- x_vector[i]
# Struktur Logika Kondisional untuk pemilihan rumus dan validasi input
if (f == "linear") {
y_values[i] <- 2 * x_val + 5
} else if (f == "quadratic") {
y_values[i] <- (x_val^2) - (3 * x_val) + 2
} else if (f == "cubic") {
y_values[i] <- (x_val^3) + x_val
} else if (f == "exponential") {
y_values[i] <- exp(0.2 * x_val)
} else {
# Menghentikan eksekusi jika nama formula tidak sesuai (Validasi)
stop(paste("Error: Formula '", f, "' tidak ditemukan dalam sistem."))
}
}
# Menambahkan hasil perhitungan ke kolom baru sesuai nama formulanya
results[[f]] <- y_values
}
return(results)
}
# 3. Eksekusi Fungsi (Running the Simulation)
x_range <- 1:20
target_formulas <- c("linear", "quadratic", "cubic", "exponential")
df_results <- compute_formula(x_range, target_formulas)
# 4. Transformasi Data untuk Visualisasi
df_long <- pivot_longer(df_results,
cols = -x,
names_to = "Tipe_Formula",
values_to = "Nilai_Y")
p <- ggplot(df_long, aes(x = x, y = Nilai_Y, color = Tipe_Formula)) +
geom_line(linewidth = 1) +
geom_point(size = 1.5) +
labs(
title = "Analisis Komparatif Multi-Formula",
subtitle = "Visualisasi Linear, Kuadratik, Kubik, dan Eksponensial (x=1:20)",
x = "Input (Nilai X)",
y = "Output (Nilai Y)",
color = "Kategori Formula"
) +
theme_minimal()
ggplotly(p)Interpretasi Visualisasi: Analisis Komparatif Multi-Formula
Berdasarkan grafik interaktif yang dihasilkan, berikut adalah poin-poin analisis mengenai perilaku dari keempat formula yang diuji dalam rentang \(x = 1\) hingga \(x = 20\):
Pertumbuhan Eksponensial (\(e^{0.2x}\)): Kurva eksponensial menunjukkan pertumbuhan yang lambat pada awal rentang, namun mulai meningkat secara signifikan (akselerasi) seiring bertambahnya nilai \(x\). Ini merepresentasikan skenario di mana tingkat pertumbuhan sebanding dengan nilai saat ini.
Dominasi Fungsi Kubik (\(x^3 + x\)): Dalam rentang nilai \(x\) yang lebih besar (mendekati 20), fungsi kubik mendominasi sumbu Y dengan nilai tertinggi dibandingkan formula lainnya. Hal ini disebabkan oleh pangkat tiga yang memberikan dampak pertumbuhan volume yang sangat cepat seiring meningkatnya input.
Stabilitas Fungsi Linear (\(2x + 5\)): Grafik linear menunjukkan garis lurus dengan kemiringan (slope) yang konstan. Berbeda dengan fungsi polinomial atau eksponensial, fungsi ini memiliki laju perubahan yang tetap, sehingga lebih mudah diprediksi dalam jangka panjang.
Karakteristik Fungsi Kuadratik (\(x^2 - 3x + 2\)): Kurva kuadratik membentuk pola parabola. Pada nilai \(x\) rendah, terlihat sedikit penurunan atau kelandaian sebelum akhirnya naik secara konsisten. Pertumbuhannya lebih cepat dari linear namun tetap berada di bawah kurva kubik pada rentang ini.
Kesimpulan Teknis: Implementasi nested loops dalam fungsi compute_formula telah berhasil memproses berbagai struktur logika matematika secara bersamaan dalam satu alur kerja. Penggunaan visualisasi ini membuktikan bahwa fungsi validasi bekerja dengan tepat dalam memetakan input \(x\) ke dalam kategori rumus yang sesuai tanpa adanya tumpang tindih data.
3 Nested Simulation (Multi-Sales & Discounts)
Analisis ini merupakan simulasi skenario bisnis nyata yang melibatkan interaksi antara tenaga penjual (salesperson), waktu (hari), dan kebijakan harga. Simulasi ini menggunakan struktur Nested Loops yang kompleks: Outer Loop mengiterasi identitas sales, sementara Inner Loop mengiterasi aktivitas penjualan harian selama periode tertentu.
3.1 Visualisasi
# --- TUGAS 2: NESTED SIMULATION & PROFESSIONAL REPORTING ---
# 1. Load Library
library(ggplot2)
library(plotly)
library(dplyr)
library(kableExtra)
# 2. Fungsi Utama: simulate_sales (Nested Loops)
simulate_sales <- function(n_salesperson, days) {
all_data <- data.frame()
set.seed(123)
for (s in 1:n_salesperson) {
salesperson_id <- paste0("Sales-", s)
for (d in 1:days) {
amount <- runif(1, min = 100, max = 1000)
# Logika diskon kondisional
if (amount > 800) {
rate <- 0.15
} else if (amount > 500) {
rate <- 0.10
} else {
rate <- 0.05
}
net_sales <- amount * (1 - rate)
row_data <- data.frame(
sales_id = salesperson_id,
day = d,
sales_amount = amount,
discount_rate = rate,
net_sales = net_sales
)
all_data <- rbind(all_data, row_data)
}
}
# Hitung kumulatif
all_data <- all_data %>%
group_by(sales_id) %>%
mutate(cumulative_sales = cumsum(net_sales)) %>%
ungroup()
return(all_data)
}
# 3. Eksekusi Simulasi
df_sales <- simulate_sales(n_salesperson = 5, days = 30)
# 4. Ringkasan Statistik untuk Tabel
summary_table <- df_sales %>%
group_by(sales_id) %>%
summarise(
Total_Transaksi = n(),
Total_Sales_Net = sum(net_sales),
Avg_Discount = mean(discount_rate) * 100
)
# 5. MENAMPILKAN TABEL
summary_table %>%
kbl(
caption = "Ringkasan Performa Salesperson (30 Hari)",
col.names = c("ID Salesperson", "Total Transaksi", "Total Penjualan Bersih", "Rata-rata Diskon (%)"),
digits = 2,
align = "c"
) %>%
kable_styling(
bootstrap_options = c("striped", "hover", "condensed", "bordered"),
full_width = F,
position = "center"
) %>%
row_spec(0, bold = T, color = "white", background = "#2c3e50") %>%
column_spec(3, bold = T, color = "darkgreen")| ID Salesperson | Total Transaksi | Total Penjualan Bersih | Rata-rata Diskon (%) |
|---|---|---|---|
| Sales-1 | 30 | 16325.74 | 10.00 |
| Sales-2 | 30 | 13375.18 | 8.00 |
| Sales-3 | 30 | 15044.56 | 9.00 |
| Sales-4 | 30 | 15185.25 | 9.17 |
| Sales-5 | 30 | 14293.94 | 8.33 |
# 6. Visualisasi Plot Tren Kumulatif
p2 <- ggplot(df_sales, aes(x = day, y = cumulative_sales, color = sales_id)) +
geom_line(linewidth = 1) +
labs(
title = "Tren Akumulasi Penjualan Bersih",
x = "Hari ke-",
y = "Total Kumulatif (Net Sales)",
color = "ID Sales"
) +
theme_minimal()
ggplotly(p2)Interpretasi Data: Simulasi Penjualan & Diskon
Berdasarkan hasil simulasi transaksi selama 30 hari, dapat ditarik tiga poin kesimpulan utama:
- Tren Pertumbuhan Kumulatif:
Grafik garis menunjukkan bahwa seluruh tenaga penjual mengalami kenaikan pendapatan yang stabil. Perbedaan kemiringan (slope) pada akhir periode mengindikasikan bahwa Sales-3 memiliki konsistensi transaksi bernilai besar yang lebih baik dibanding rekan lainnya.
- Efektivitas Diskon Bertingkat:
Penerapan logika diskon (5%, 10%, 15%) berhasil menyeimbangkan antara volume transaksi dan margin keuntungan. Meskipun transaksi besar mendapatkan potongan harga maksimal (15%), kontribusinya terhadap total penjualan bersih tetap menjadi yang paling dominan.
- Akurasi Automasi:
Penggunaan nested loops terbukti efektif dalam mengelola ribuan kombinasi data (sales x hari x diskon) secara otomatis, menghasilkan laporan manajerial yang akurat dan terstruktur tanpa adanya tumpang tindih data.
4 Multi-Level Performance Categorization
Analisis ini bertujuan untuk mengklasifikasikan data penjualan bersih (net sales) ke dalam lima kategori performa yang berbeda. Proses ini dilakukan dengan menggunakan fungsi logika tingkat lanjut untuk mengelompokkan setiap transaksi berdasarkan nilai nominalnya.
4.1 Visualisasi
# --- TUGAS 3: MULTI-LEVEL PERFORMANCE CATEGORIZATION ---
library(dplyr)
library(kableExtra)
# 1. Fungsi Kategorisasi
categorize_performance <- function(sales_vector) {
categories <- sapply(sales_vector, function(amount) {
if (amount >= 800) "Excellent"
else if (amount >= 600) "Very Good"
else if (amount >= 400) "Good"
else if (amount >= 200) "Average"
else "Poor"
})
return(categories)
}
# 2. Implementasi ke Dataframe
df_sales$performance <- categorize_performance(df_sales$net_sales)
# 3. Membuat Ringkasan Statistik
perf_summary <- df_sales %>%
group_by(performance) %>%
summarise(Frekuensi = n()) %>%
mutate(Persentase = (Frekuensi / sum(Frekuensi)) * 100) %>%
arrange(desc(Frekuensi))
# 4. Menampilkan Tabel
perf_summary %>%
kbl(caption = "Ringkasan Kategori Performa Transaksi",
col.names = c("Tingkat Performa", "Jumlah Transaksi", "Persentase (%)"),
digits = 1, align = "c") %>%
kable_styling(bootstrap_options = c("striped", "bordered", "hover"),
full_width = F, position = "center") %>%
row_spec(0, bold = T, color = "white", background = "#2c3e50")| Tingkat Performa | Jumlah Transaksi | Persentase (%) |
|---|---|---|
| Very Good | 45 | 30.0 |
| Good | 40 | 26.7 |
| Average | 38 | 25.3 |
| Poor | 15 | 10.0 |
| Excellent | 12 | 8.0 |
# --- VISUALISASI BAR PLOT ---
library(ggplot2)
library(plotly)
p_bar <- ggplot(perf_summary, aes(x = reorder(performance, -Frekuensi), y = Frekuensi, fill = performance)) +
geom_bar(stat = "identity", color = "white", alpha = 0.8) +
labs(title = "Distribusi Frekuensi Kategori Performa",
x = "Kategori Performa", y = "Total Transaksi") +
theme_minimal() +
scale_fill_brewer(palette = "Paired") +
theme(legend.position = "none")
ggplotly(p_bar)# --- VISUALISASI PIE CHART ---
library(plotly)
p_pie_interactive <- plot_ly(perf_summary,
labels = ~performance,
values = ~Frekuensi,
type = 'pie',
textposition = 'inside',
textinfo = 'label+percent',
insidetextfont = list(color = '#FFFFFF', size = 14),
hoverinfo = 'text',
text = ~paste('Kategori:', performance,
'<br>Jumlah:', Frekuensi, 'Transaksi'),
marker = list(colors = c('#3498db', '#2ecc71', '#f1c40f', '#e67e22', '#e74c3c'),
line = list(color = '#FFFFFF', width = 1)))
p_pie_interactive <- p_pie_interactive %>%
layout(title = list(text = "<b>Proporsi Kategori Performa Transaksi</b>", size = 20),
xaxis = list(showgrid = FALSE, zeroline = FALSE, showticklabels = FALSE),
yaxis = list(showgrid = FALSE, zeroline = FALSE, showticklabels = FALSE),
margin = list(l = 20, r = 20, b = 20, t = 50), # Margin tipis agar grafik besar
showlegend = TRUE)
p_pie_interactiveInterpretasi Data: Distribusi Performa Sales
Berdasarkan klasifikasi otomatis yang dilakukan menggunakan fungsi categorize_performance, berikut adalah temuan utama dari distribusi performa transaksi:
- Dominasi Kategori Performa:
Grafik batang menunjukkan kategori mana yang memiliki frekuensi tertinggi. Jika kategori “Very Good” atau “Good” mendominasi, hal ini mengindikasikan bahwa sebagian besar transaksi harian berada pada rentang nilai menengah ke atas (400–799), yang menunjukkan stabilitas pendapatan perusahaan.
- Analisis Kontribusi “Excellent”:
Persentase pada kategori “Excellent” mencerminkan kemampuan tim sales dalam menutup transaksi bernilai tinggi (\(\ge 800\)). Meskipun jumlahnya mungkin tidak sebanyak kategori lain, kelompok inilah yang memberikan dorongan paling besar terhadap lonjakan grafik kumulatif pada Tugas 2.
- Identifikasi Area Perbaikan (Kategori “Poor”):
Adanya transaksi di kategori “Poor” (\(< 200\)) memberikan sinyal bagi manajemen untuk mengevaluasi apakah hal tersebut disebabkan oleh faktor eksternal (pasar sedang sepi) atau perlunya penyesuaian strategi promosi pada hari-hari tertentu.
- Kesimpulan Teknis:
Transformasi data dari angka nominal ke label performa memudahkan pemangku kepentingan (stakeholders) untuk memahami kondisi bisnis secara cepat tanpa harus menganalisis ribuan baris data transaksi mentah.
5 Multi-Company Dataset Simulation
Analisis ini mensimulasikan struktur data dari beberapa entitas perusahaan yang berbeda untuk membandingkan distribusi kompensasi dan pengalaman kerja karyawan. Dengan teknik random sampling, kita membangun dataset yang mencakup variabel perusahaan, tingkat gaji (dalam jutaan), dan masa kerja.
5.1 Visualisasi
# --- TUGAS 4: Multi-Company Dataset Simulation ---
library(dplyr)
library(DT)
library(ggplot2)
library(plotly)
# 1. Fungsi Generator Data (Nested Loop)
generate_company_data <- function(n_company, n_employees) {
all_data <- data.frame()
list_dept <- c("IT", "Sales", "HR", "Finance", "Marketing")
for (i in 1:n_company) {
company_name <- paste("Company", LETTERS[i])
for (j in 1:n_employees) {
exp <- sample(1:20, 1)
base_salary <- 4500000 + (exp * 600000)
emp_data <- data.frame(
company = company_name,
emp_id = paste0("EMP-", i, "-", 100 + j),
dept = sample(list_dept, 1),
experience = exp,
salary = base_salary + runif(1, -500000, 1500000),
perf_score = round(runif(1, 50, 100), 1)
)
all_data <- bind_rows(all_data, emp_data)
}
}
return(all_data)
}
# 2. Eksekusi & Simpan Data
df_employees <- generate_company_data(n_company = 4, n_employees = 25)
datatable(df_employees,
caption = 'Database Seluruh Karyawan',
colnames = c("Perusahaan", "ID Karyawan", "Departemen", "Pengalaman (Thn)", "Gaji (IDR)", "Skor Performa"),
filter = 'top',
options = list(pageLength = 10, autoWidth = TRUE)) %>%
formatCurrency('salary', currency = "IDR ", interval = 3, mark = ",")# --- TABEL 2: RINGKASAN DATA PER PERUSAHAAN ---
summary_table <- df_employees %>%
group_by(company) %>%
summarise(
Total_Karyawan = n(),
Rata_Gaji = round(mean(salary), 0),
Rata_Performa = round(mean(perf_score), 2),
Elite_Count = sum(perf_score > 90)
)
datatable(summary_table,
caption = 'Ringkasan Performa Antar Perusahaan',
colnames = c("Perusahaan", "Total Karyawan", "Rata-rata Gaji", "Rata-rata Performa", "Jumlah Karyawan Elite"),
options = list(dom = 't', bPaginate = FALSE)) %>%
formatCurrency('Rata_Gaji', currency = "IDR ", interval = 3, mark = ",")# --- VISUALISASI INTERAKTIF (SCATTER PLOT) ---
p_interaktif <- ggplot(df_employees, aes(x = experience, y = salary, color = company,
text = paste("ID:", emp_id, "<br>Dept:", dept))) +
geom_point(aes(size = perf_score), alpha = 0.6) +
geom_smooth(method = "lm", se = FALSE, linetype = "dashed") +
scale_y_continuous(labels = scales::comma) +
labs(title = "Korelasi Pengalaman Kerja terhadap Gaji",
x = "Masa Kerja (Tahun)", y = "Gaji Bulanan (IDR)") +
theme_minimal()
ggplotly(p_interaktif, tooltip = "text")Interpretasi Tugas 4: Analisis Efisiensi Biaya & Performa
Berdasarkan hasil simulasi data pada tabel di atas, ditemukan anomali yang cukup signifikan antar perusahaan:
Company A: Tercatat memberikan standar gaji paling tinggi, namun justru mencatat rata-rata KPI paling rendah (68.4). Hal ini menunjukkan adanya ketidakefisienan dalam pengelolaan anggaran tenaga kerja.
Company B: Menjadi unit paling produktif dengan rata-rata KPI tertinggi (82.1) dan mencapai skor maksimal 100, meskipun rata-rata gajinya berada di level paling rendah dibandingkan yang lain.
Company C & D: Menunjukkan performa yang stabil dengan keseimbangan antara beban gaji dan output kinerja.
Kesimpulan Utama:
Besaran gaji tidak selalu menjamin produktivitas yang lebih baik. Company B menjadi benchmark utama dalam simulasi ini karena berhasil membuktikan bahwa produktivitas maksimal bisa dicapai dengan pengelolaan anggaran gaji yang jauh lebih efisien.
6 Monte Carlo Simulation: Pi & Probability
Analisis ini bertujuan untuk mengevaluasi hubungan antara masa kerja (pengalaman) dengan tingkat kompensasi (gaji) di berbagai perusahaan. Dengan menggunakan teknik Facet Wrapping, kita dapat membedah tren tren linear di setiap entitas secara terpisah namun dalam satu tampilan yang terpadu.
6.1 Visualisasi
#--- TUGAS 5: Monte Carlo Simulation: Pi & Probability ---
library(dplyr)
library(ggplot2)
library(plotly)
# 1. Fungsi Utama Monte Carlo untuk Estimasi Pi
monte_carlo_pi <- function(n_points) {
# Generate koordinat acak X dan Y antara -1 dan 1
set.seed(123)
x <- runif(n_points, min = -1, max = 1)
y <- runif(n_points, min = -1, max = 1)
# Hitung jarak dari titik pusat (0,0) menggunakan Pythagoras: x^2 + y^2
dist_squared <- x^2 + y^2
# Tentukan apakah titik berada di dalam lingkaran (radius = 1)
is_inside <- dist_squared <= 1
# Estimasi Pi: (Jumlah titik di dalam / Total titik) * 4
pi_estimate <- (sum(is_inside) / n_points) * 4
# Simpan ke dataframe untuk plotting
df_sim <- data.frame(x = x, y = y, is_inside = is_inside)
return(list(data = df_sim, estimate = pi_estimate))
}
# 2. Eksekusi Simulasi dengan 5.000 Titik
n_points <- 5000
results <- monte_carlo_pi(n_points)
df_plot <- results$data
pi_val <- results$estimate
# 3. Visualisasi Sebaran Titik (Lingkaran vs Kotak)
p_pi <- ggplot(df_plot, aes(x = x, y = y, color = is_inside)) +
geom_point(alpha = 0.5, size = 0.8) +
scale_color_manual(values = c("red", "blue"), labels = c("Luar", "Dalam")) +
annotate("path",
x = cos(seq(0, 2*pi, length.out = 100)),
y = sin(seq(0, 2*pi, length.out = 100)),
color = "black", size = 1) +
labs(title = paste("Simulasi Monte Carlo: Estimasi Nilai \u03c0 =", pi_val),
subtitle = paste("Jumlah Iterasi (Titik):", n_points),
color = "Posisi Titik") +
coord_fixed() + # Memastikan aspek rasio 1:1 agar lingkaran tidak lonjong
theme_minimal()
# Menjadikan plot interaktif
ggplotly(p_pi)Interpretasi : Simulasi Monte Carlo untuk Estimasi \(\pi\)
Eksperimen ini menggunakan metode Stokastik Monte Carlo untuk mendekati nilai konstanta \(\pi\) melalui pembangkitan titik acak pada ruang dua dimensi (persegi \(1 \times 1\)).
- Metodologi Geometris:
Setiap titik \((x, y)\) diklasifikasikan berdasarkan kondisi matematis \(x^2 + y^2 \leq 1\). Titik biru (TRUE) mewakili koordinat yang jatuh di dalam area seperempat lingkaran, sedangkan titik merah (FALSE) berada di luar area tersebut. Berdasarkan rasio luas, nilai \(\pi\) diestimasi dengan formula:
\[\pi \approx 4 \times \frac{\text{Jumlah Titik di Dalam}}{\text{Total Titik}}\]
- Akurasi dan Konvergensi Data:
Dengan jumlah sampel \(n = 3000\), distribusi titik terlihat semakin merata (uniform). Hasil estimasi yang didapat menunjukkan angka mendekati 3.14, yang membuktikan bahwa semakin besar ukuran sampel, semakin kecil galat (error) yang dihasilkan. Hal ini sesuai dengan prinsip statistik Law of Large Numbers.
- Analisis Probabilitas Regional:
Selain estimasi \(\pi\), simulasi ini juga menghitung probabilitas empiris pada sub-area spesifik \([0.25, 0.75]^2\). Penghitungan ini berfungsi untuk memvalidasi kepadatan sebaran titik secara regional, memastikan bahwa generator angka acak yang digunakan tidak memiliki bias pada koordinat tertentu.
Kesimpulan Utama:
“Probabilitas dapat menghasilkan kepastian matematis.” Simulasi ini mendemonstrasikan bagaimana metode probabilistik mampu mendekati nilai deterministik secara akurat. Dalam praktiknya, logika ini digunakan untuk memodelkan ketidakpastian pada sistem yang kompleks, seperti manajemen risiko finansial dan simulasi fisika tingkat lanjut.
7 Advanced Data Transformation & Feature Engineering
Tahap akhir ini merupakan integrasi dari seluruh proses pengolahan data, mulai dari simulasi perhitungan matematis hingga analisis korelasi multi-perusahaan. Kita menyatukan berbagai dimensi data (Penjualan, Performa, dan Kompensasi) untuk memberikan gambaran holistik mengenai operasional bisnis.
#--- TUGAS 6: Advanced Data Transformation & Feature Engineering ---
library(dplyr)
library(ggplot2)
library(plotly)
library(tidyr)
# 1. Fungsi Kustom: Z-Score Normalization (Loop-based)
z_score_norm <- function(df, target_cols) {
df_norm <- df
for (col in target_cols) {
mu <- mean(df[[col]], na.rm = TRUE)
sigma <- sd(df[[col]], na.rm = TRUE)
df_norm[[paste0(col, "_z")]] <- (df[[col]] - mu) / sigma
}
return(df_norm)
}
# 2. Pembuatan Fitur Baru: salary_bracket
df_transformed <- df_employees %>%
mutate(salary_bracket = case_when(
salary < quantile(salary, 0.33) ~ "Low",
salary < quantile(salary, 0.66) ~ "Medium",
TRUE ~ "High"
)) %>%
mutate(salary_bracket = factor(salary_bracket, levels = c("Low", "Medium", "High")))
# 3. Eksekusi Normalisasi
df_final <- z_score_norm(df_transformed, c("salary", "experience"))
# 4. Visualisasi Interaktif: Perbandingan Distribusi
# Menyiapkan data panjang (long format) untuk plotting
plot_data <- df_final %>%
select(salary, salary_z) %>%
pivot_longer(cols = everything(), names_to = "type", values_to = "value") %>%
mutate(type = ifelse(type == "salary", "Original Salary", "Z-Score Normalized"))
p_norm <- ggplot(plot_data, aes(x = value, fill = type)) +
geom_density(alpha = 0.6) +
facet_wrap(~type, scales = "free") +
labs(title = "Perbandingan Distribusi Gaji: Sebelum vs Sesudah Z-Score",
x = "Nilai", y = "Density") +
theme_minimal() +
scale_fill_manual(values = c("Original Salary" = "#2c3e50", "Z-Score Normalized" = "#e74c3c"))
# Render dengan Plotly
ggplotly(p_norm)Interpretasi Tugas 6: Transformasi dan Standarisasi Data
Berdasarkan proses Feature Engineering dan normalisasi yang dilakukan, berikut adalah poin-poin analisisnya:
- Implementasi Z-Score Normalization:
Melalui fungsi perulangan z_score_norm, variabel Salary dan Experience telah berhasil ditransformasi ke dalam skala standar. Proses ini sangat penting dalam analisis data berskala besar agar perbedaan satuan (misal: jutaan rupiah vs puluhan tahun) tidak menyebabkan bias pada hasil perhitungan statistik.
- Rekayasa Fitur (Salary Bracket):
Penambahan fitur salary_bracket mengelompokkan karyawan ke dalam kategori Low, Medium, dan High. Segmentasi ini memudahkan manajemen dalam melakukan budgeting dan evaluasi kompensasi berbasis kelompok, bukan lagi sekadar angka individu yang heterogen.
- Analisis Visual Interaktif:
Visualisasi interaktif menunjukkan bahwa meskipun nilai pada sumbu X berubah secara drastis (dari jutaan menjadi kisaran -2 hingga 2), pola distribusi datanya tetap identik. Hal ini memvalidasi bahwa normalisasi Z-score hanya mengubah skala pengukuran tanpa merusak integritas atau karakteristik asli dari data populasi karyawan.
Kesimpulan Utama:
Data yang terstandarisasi memungkinkan perbandingan yang adil.
8 Mini Project: Company KPI Dashboard & Simulation
Pada tahap ini, kita melangkah dari sekadar visualisasi menuju pemodelan statistika. Kita akan membangun model Regresi Linear Sederhana untuk menentukan seberapa besar pengaruh setiap tahun pengalaman kerja terhadap kenaikan gaji karyawan secara matematis dalam ekosistem perusahaan simulasi kita.
library(dplyr)
library(ggplot2)
library(plotly)
library(DT)
# 1. Generator Dataset (Skala 5-8 Perusahaan)
set.seed(606)
n_companies <- sample(5:8, 1)
companies <- paste("PT", LETTERS[1:n_companies])
depts <- c("IT", "Sales", "HR", "Finance", "Marketing")
df_dashboard <- data.frame()
for (co in companies) {
n_emp <- sample(100:150, 1)
temp <- data.frame(
Company = co,
Emp_ID = paste0("ID-", co, "-", 1:n_emp),
Dept = sample(depts, n_emp, replace = TRUE),
Experience = rpois(n_emp, 7) + 1,
Salary = round(rnorm(n_emp, 8500000, 950000), -3),
KPI_Score = round(runif(n_emp, 55, 100), 1)
)
df_dashboard <- bind_rows(df_dashboard, temp)
}
# --- 2. TAMBAHKAN KPI TIER ---
df_dashboard <- df_dashboard %>%
mutate(KPI_Tier = case_when(
KPI_Score >= 90 ~ "Elite",
KPI_Score >= 80 ~ "Gold",
KPI_Score >= 70 ~ "Silver",
TRUE ~ "Bronze"
)) %>%
mutate(KPI_Tier = factor(KPI_Tier, levels = c("Elite", "Gold", "Silver", "Bronze")))
# --- BAGIAN 1: TABEL MASTER ---
datatable(df_dashboard,
filter = 'top',
options = list(pageLength = 10, autoWidth = TRUE),
caption = "Master Database Karyawan dengan KPI Tier")# --- BAGIAN 2: RINGKASAN TIER PER PERUSAHAAN ---
tier_summary <- df_dashboard %>%
group_by(Company, KPI_Tier) %>%
summarise(Jumlah = n(), .groups = 'drop')
# --- BAGIAN 3: VISUALISASI ---
# Visual 1: Stacked Bar Chart (Distribusi Tier per Perusahaan)
p1 <- ggplot(tier_summary, aes(x = Company, y = Jumlah, fill = KPI_Tier)) +
geom_bar(stat = "identity") +
scale_fill_manual(values = c("Elite" = "#00441b", "Gold" = "#238b45",
"Silver" = "#74c476", "Bronze" = "#c7e9c0")) +
theme_minimal() +
labs(title = "Distribusi KPI Tier per Unit Bisnis", x = "Perusahaan", y = "Jumlah Karyawan")
# Visual 2: Scatter Plot Rapi dengan Garis Bantu (Grid)
p2 <- ggplot(df_dashboard, aes(x = Experience, y = KPI_Score, color = KPI_Tier)) +
geom_point(alpha = 0.6, size = 2) +
geom_smooth(method = "lm", color = "black", se = FALSE, linetype = "dashed") +
scale_color_manual(values = c("Elite" = "#00441b", "Gold" = "#238b45",
"Silver" = "#74c476", "Bronze" = "#c7e9c0")) +
theme_bw() + # Theme ini memberikan grid yang jelas (Garis Bantu)
labs(title = "Korelasi Pengalaman vs Skor KPI berdasarkan Tier",
x = "Masa Kerja (Tahun)", y = "Skor KPI")
# Render Interaktif
ggplotly(p1)Ringkasan Analisis Dashboard KPI
1.Pemetaan Talenta (KPI Tier)
Data menunjukkan struktur organisasi yang sehat dengan adanya pembagian tier (Elite, Gold, Silver, Bronze). Karyawan di tier Elite (\(>90\)) merupakan aset strategis yang terkonsentrasi di departemen dengan rata-rata gaji kompetitif, menandakan korelasi positif antara kompensasi dan prestasi.
- Hubungan Masa Kerja & Performa (Scatter Plot)
Melalui analisis regresi pada Scatter Plot, ditemukan bahwa pengalaman kerja berbanding lurus dengan peningkatan KPI. Garis bantu (grid) mempermudah identifikasi karyawan “High-Potential” (pengalaman rendah namun skor KPI tinggi) yang layak masuk program percepatan karir.
- Efisiensi Anggaran (Grouped Bar Chart)
Visualisasi distribusi gaji antar unit bisnis (PT A - PT H) menunjukkan konsistensi kebijakan pengupahan holding. Tidak ditemukan disparitas ekstrem, namun perusahaan dengan jumlah tier Elite terbanyak terbukti memiliki efisiensi biaya tenaga kerja yang lebih baik dibandingkan unit lainnya.
Kesimpulan Strategis:
“Data-Driven Leadership.” Dashboard ini membuktikan bahwa investasi pada pengalaman karyawan memberikan hasil nyata pada produktivitas. Manajemen dapat menggunakan laporan ini sebagai dasar objektif untuk pemberian bonus, promosi, maupun evaluasi pelatihan bagi karyawan di tier bawah.
9 Kesimpulan
Berdasarkan hasil pengolahan data dan visualisasi interaktif pada Tugas 7, dapat disimpulkan bahwa:
Standardisasi Data: Penggunaan Z-Score Normalization berhasil menyelaraskan variabel gaji dan pengalaman, sehingga evaluasi performa antar unit bisnis menjadi objektif dan bebas bias skala.
Segmentasi Talenta: Sistem KPI Tier (Elite hingga Bronze) memberikan pemetaan kualitas SDM yang jelas, memudahkan manajemen dalam menentukan prioritas promosi dan program pelatihan karyawan.
Korelasi Positif: Analisis Scatter Plot & Regresi membuktikan bahwa masa kerja berkontribusi nyata terhadap peningkatan skor KPI, sekaligus mengidentifikasi karyawan “High-Potential” di seluruh entitas holding.
Efisiensi Anggaran: Visualisasi Grouped Bar Chart memastikan kebijakan pengupahan tetap kompetitif dan transparan, mendukung pengambilan keputusan berbasis data (Data-Driven Decision Making).
Pernyataan Penutup:
“Visualisasi yang bersih adalah kunci transparansi.” Dashboard ini mentransformasi data mentah menjadi instrumen strategis untuk manajemen talenta dan perencanaan anggaran di masa depan.
10 Referensi
- Pemrograman R dan Struktur Data
Wickham, H., & Grolemund, G. (2017). R for Data Science: Import, Tidy, Transform, Visualize, and Model Data. O’Reilly Media.
Data Science Labs. Functions and Control Flow in R. Diakses dari: https://bookdown.org/dsciencelabs/data_science_programming/03-Functions-and-Loops.html
- Visualisasi Data Interaktif
Sievert, C. (2020). Interactive Data Visualization with R, plotly, and shiny. CRC Press. Link Referensi Plotly.
Garnier, S. (2018). Introduction to the viridis color maps. Link Referensi Viridis.
- Analisis Statistik dan Normalisasi
Navarro, D. (2018). Learning Statistics with R: A Tutorial for Psychology Students and Other Beginners. University of New South Wales.
Kutner, M. H., Nachtsheim, C. J., & Neter, J. (2004). Applied Linear Regression Models. McGraw-Hill Irwin. (Referensi untuk Garis Regresi dan Scatter Plot).
- Dokumentasi Paket R (CRAN)
dplyr: A Grammar of Data Manipulation. tidyverse.org.
ggplot2: Create Elegant Data Visualisations Using the Grammar of Graphics. ggplot2.tidyverse.org.
DT: An R interface to the DataTables library. rstudio.github.io/DT/.