Analisis data eksploratif merupakan tahap penting untuk memahami struktur, kualitas, dan karakteristik data sebelum dilakukan analisis lanjutan. Artikel ini membahas dataset insiden kriminalitas yang telah melalui proses pembersihan, dengan fokus pada perbandingan profil demografi korban dan tersangka. Data yang digunakan memuat identitas kode, usia, gender, ras tersangka, serta kategori kejahatan. Tahapan analisis meliputi pemeriksaan struktur data, evaluasi nilai hilang, ringkasan statistik, eksplorasi distribusi usia dan kategori, serta transformasi variabel kategorik dan numerik. Visualisasi digunakan untuk menyajikan pola secara lebih komunikatif. Hasil analisis perlu dipahami sebagai gambaran deskriptif dari data yang tersedia, bukan sebagai bukti hubungan sebab-akibat atau representasi seluruh kriminalitas. Keterbatasan variabel dalam file kerja juga menjadi pertimbangan dalam menentukan analisis yang dapat dilakukan secara valid.
Kata kunci: analisis data eksploratif, kriminalitas, demografi, data cleaning, encoding, Z-Score.
Data kriminalitas memiliki karakteristik yang beragam, mulai dari informasi kejadian, lokasi dan waktu, hingga karakteristik pihak yang terlibat. Data yang belum tertata dengan baik berpotensi mengandung nilai hilang, format tidak konsisten, kesalahan penulisan, dan nilai yang tidak masuk akal. Oleh karena itu, pemeriksaan kualitas dan penyiapan data menjadi langkah awal sebelum menarik informasi dari data.
Artikel ini mengembangkan materi presentasi Kelompok 3 menjadi laporan eksploratif berbasis R. Fokus utamanya adalah profil demografi korban dan tersangka serta gambaran kategori kejahatan berdasarkan dataset hasil pembersihan yang disediakan. Pendekatan eksploratif dipilih agar pola utama dapat dikenali melalui statistik deskriptif dan visualisasi yang mudah ditafsirkan.
Tujuan analisis ini adalah: - Mengidentifikasi struktur dan kelengkapan dataset yang digunakan. - Mendeskripsikan distribusi usia dan gender korban maupun tersangka. - Mengamati sebaran kategori kejahatan pada data yang tersedia. - Menjelaskan penerapan encoding pada variabel kategorik dan standardisasi Z-Score pada variabel usia. - Menyajikan hasil eksplorasi sebagai dasar untuk analisis lanjutan dengan tetap memperhatikan keterbatasan data.
Dataset kerja yang digunakan adalah file Excel
Crime_Incidents_Clean Kelompok Mantull.xlsx. File berisi
data hasil pembersihan dengan satu baris merepresentasikan pasangan
informasi korban dan tersangka pada suatu catatan. Berdasarkan
pemeriksaan file, dataset memuat ** baris dan variabel**.
Variabel yang tersedia meliputi kode korban, nama korban, usia dan gender korban, kode tersangka, nama tersangka, usia dan gender tersangka, ras tersangka, serta kategori kejahatan. Karena file kerja ini merupakan versi yang telah diringkas/dibersihkan, tidak seluruh variabel dari dataset awal dalam presentasi tersedia di dalamnya.
Pengolahan dilakukan menggunakan R dan RStudio dengan paket
readxl, dplyr, tidyr,
ggplot2, dan knitr. Analisis bersifat
deskriptif-eksploratif, melalui pemeriksaan struktur, ringkasan
statistik, tabulasi kategori, dan visualisasi.
Pastikan file Excel berada di folder kerja yang sama dengan dokumen R
Markdown ini. Jika nama file atau lokasi berbeda, sesuaikan nilai
file_data pada kode berikut.
file_data <- "Crime_Incidents_Clean Kelompok Mantull.xlsx"
data <- read_excel(file_data)
# Menyamakan nama kolom agar mudah dipanggil dalam R
names(data) <- make.names(names(data))
dim(data)
## [1] 5249 10
# Hanya menampilkan variabel analisis; nama dan kode identitas tidak dipublikasikan
data %>%
select(Victim.Age.Clean, Victim.Gender.Clean,
Suspect.Age.Clean, Suspect.Gender.Clean,
Suspect.Race.Clean, Crime.Category) %>%
head(6) %>%
kable(caption = "Contoh variabel analisis (tanpa nama dan kode identitas)")
| Victim.Age.Clean | Victim.Gender.Clean | Suspect.Age.Clean | Suspect.Gender.Clean | Suspect.Race.Clean | Crime.Category |
|---|---|---|---|---|---|
| 51 | Unknown | 51 | Male | Asian | Assault & Battery |
| 50 | Unknown | 46 | Other | Black | Burglary / B&E |
| 29 | Other | 19 | Female | Asian | Other |
| 50 | Unknown | 46 | Male | Black | Property Damage |
| 51 | Male | 75 | Female | White | Domestic Violence |
| 15 | Unknown | 73 | Unknown | White | Burglary / B&E |
str(data)
## tibble [5,249 × 10] (S3: tbl_df/tbl/data.frame)
## $ Victim.ID : chr [1:5249] "VIC00642" "VIC00262" "VIC00518" "VIC00243" ...
## $ Victim.Name : chr [1:5249] "Robert Torres" "John Martin" "Richard Hill" "Susan Young" ...
## $ Victim.Age.Clean : num [1:5249] 51 50 29 50 51 15 72 50 55 10 ...
## $ Victim.Gender.Clean : chr [1:5249] "Unknown" "Unknown" "Other" "Unknown" ...
## $ Suspect.ID : chr [1:5249] "SUS00281" "SUS00376" "SUS00560" "SUS00468" ...
## $ Suspect.Name : chr [1:5249] "Barbara Thomas" "Barbara Harris" "Richard Scott" "Michael Thomas" ...
## $ Suspect.Age.Clean : num [1:5249] 51 46 19 46 75 73 58 73 26 46 ...
## $ Suspect.Gender.Clean: chr [1:5249] "Male" "Other" "Female" "Male" ...
## $ Suspect.Race.Clean : chr [1:5249] "Asian" "Black" "Asian" "Black" ...
## $ Crime.Category : chr [1:5249] "Assault & Battery" "Burglary / B&E" "Other" "Property Damage" ...
tipe_variabel <- data.frame(
Variabel = names(data),
Tipe = vapply(data, function(x) paste(class(x), collapse = ", "), character(1)),
Jumlah_NA = vapply(data, function(x) sum(is.na(x)), integer(1))
)
kable(tipe_variabel, caption = "Tipe variabel dan jumlah nilai hilang")
| Variabel | Tipe | Jumlah_NA | |
|---|---|---|---|
| Victim.ID | Victim.ID | character | 0 |
| Victim.Name | Victim.Name | character | 0 |
| Victim.Age.Clean | Victim.Age.Clean | numeric | 0 |
| Victim.Gender.Clean | Victim.Gender.Clean | character | 0 |
| Suspect.ID | Suspect.ID | character | 0 |
| Suspect.Name | Suspect.Name | character | 0 |
| Suspect.Age.Clean | Suspect.Age.Clean | numeric | 0 |
| Suspect.Gender.Clean | Suspect.Gender.Clean | character | 0 |
| Suspect.Race.Clean | Suspect.Race.Clean | character | 0 |
| Crime.Category | Crime.Category | character | 0 |
Pemeriksaan struktur membantu memastikan bahwa kolom usia terbaca sebagai numerik, sedangkan kode dan kategori diperlakukan sebagai variabel kategorik atau teks. Pengecekan ini penting karena tipe data yang tidak sesuai dapat menghambat perhitungan statistik dan pembuatan grafik.
missing_tbl <- data.frame(
Variabel = names(data),
Jumlah_Missing = vapply(data, function(x) sum(is.na(x)), integer(1)),
Persentase_Missing = round(vapply(data, function(x) mean(is.na(x)) * 100, numeric(1)), 2)
)
kable(missing_tbl, caption = "Pemeriksaan missing value")
| Variabel | Jumlah_Missing | Persentase_Missing | |
|---|---|---|---|
| Victim.ID | Victim.ID | 0 | 0 |
| Victim.Name | Victim.Name | 0 | 0 |
| Victim.Age.Clean | Victim.Age.Clean | 0 | 0 |
| Victim.Gender.Clean | Victim.Gender.Clean | 0 | 0 |
| Suspect.ID | Suspect.ID | 0 | 0 |
| Suspect.Name | Suspect.Name | 0 | 0 |
| Suspect.Age.Clean | Suspect.Age.Clean | 0 | 0 |
| Suspect.Gender.Clean | Suspect.Gender.Clean | 0 | 0 |
| Suspect.Race.Clean | Suspect.Race.Clean | 0 | 0 |
| Crime.Category | Crime.Category | 0 | 0 |
Nilai hilang tidak secara otomatis harus dihapus. Penanganannya perlu
mempertimbangkan tujuan analisis dan alasan nilai tersebut tidak
tersedia. Pada laporan ini, ringkasan dihitung dengan mengabaikan nilai
NA pada variabel numerik, sedangkan data mentah tetap
dipertahankan.
data <- data %>%
mutate(
Victim.Age.Clean = as.numeric(Victim.Age.Clean),
Suspect.Age.Clean = as.numeric(Suspect.Age.Clean)
)
validasi_usia <- data.frame(
Variabel = c("Usia korban", "Usia tersangka"),
Missing = c(sum(is.na(data$Victim.Age.Clean)), sum(is.na(data$Suspect.Age.Clean))),
Di_bawah_0 = c(sum(data$Victim.Age.Clean < 0, na.rm = TRUE),
sum(data$Suspect.Age.Clean < 0, na.rm = TRUE)),
Di_atas_120 = c(sum(data$Victim.Age.Clean > 120, na.rm = TRUE),
sum(data$Suspect.Age.Clean > 120, na.rm = TRUE))
)
kable(validasi_usia, caption = "Pemeriksaan kewajaran usia")
| Variabel | Missing | Di_bawah_0 | Di_atas_120 |
|---|---|---|---|
| Usia korban | 0 | 0 | 0 |
| Usia tersangka | 0 | 0 | 0 |
Pemeriksaan rentang usia di atas merupakan penanda awal untuk meninjau nilai yang berpotensi tidak wajar. Batas tersebut digunakan sebagai aturan pemeriksaan eksploratif, bukan sebagai pengganti verifikasi terhadap sumber data asli. Nilai yang meragukan sebaiknya ditelusuri terlebih dahulu dan tidak diubah secara sembarang.
ringkasan_usia <- data.frame(
Variabel = c("Usia korban", "Usia tersangka"),
N_tersedia = c(sum(!is.na(data$Victim.Age.Clean)), sum(!is.na(data$Suspect.Age.Clean))),
Rata_rata = c(mean(data$Victim.Age.Clean, na.rm = TRUE),
mean(data$Suspect.Age.Clean, na.rm = TRUE)),
Median = c(median(data$Victim.Age.Clean, na.rm = TRUE),
median(data$Suspect.Age.Clean, na.rm = TRUE)),
Simpangan_baku = c(sd(data$Victim.Age.Clean, na.rm = TRUE),
sd(data$Suspect.Age.Clean, na.rm = TRUE)),
Minimum = c(min(data$Victim.Age.Clean, na.rm = TRUE),
min(data$Suspect.Age.Clean, na.rm = TRUE)),
Maksimum = c(max(data$Victim.Age.Clean, na.rm = TRUE),
max(data$Suspect.Age.Clean, na.rm = TRUE))
)
ringkasan_usia[-which(!is.finite(ringkasan_usia$Rata_rata)), ] %>%
mutate(across(where(is.numeric), ~round(.x, 2))) %>%
kable(caption = "Statistik deskriptif usia korban dan tersangka")
| Variabel | N_tersedia | Rata_rata | Median | Simpangan_baku | Minimum | Maksimum |
|---|
Rata-rata memberikan gambaran pusat data, sedangkan median dapat menjadi ukuran pusat yang lebih tahan terhadap nilai ekstrem. Simpangan baku menunjukkan tingkat keragaman usia terhadap rata-ratanya. Perbandingan ukuran-ukuran tersebut memberikan gambaran awal mengenai perbedaan distribusi usia korban dan tersangka.
usia_long <- data %>%
select(Victim.Age.Clean, Suspect.Age.Clean) %>%
pivot_longer(cols = everything(), names_to = "Kelompok", values_to = "Usia") %>%
mutate(Kelompok = recode(Kelompok,
Victim.Age.Clean = "Korban",
Suspect.Age.Clean = "Tersangka")) %>%
filter(!is.na(Usia), Usia >= 0, Usia <= 120)
ggplot(usia_long, aes(x = Usia, fill = Kelompok)) +
geom_histogram(binwidth = 5, color = "white", alpha = 0.85) +
facet_wrap(~Kelompok, ncol = 1) +
labs(title = "Distribusi Usia Korban dan Tersangka",
x = "Usia (tahun)", y = "Frekuensi",
caption = "Grafik menampilkan usia 0–120 tahun untuk eksplorasi.") +
theme_minimal() +
theme(legend.position = "none")
Histogram memperlihatkan frekuensi usia pada interval tertentu. Puncak histogram menunjukkan interval usia dengan catatan terbanyak, sementara lebar sebaran menggambarkan variasi usia. Grafik ini bersifat deskriptif dan tidak dengan sendirinya menjelaskan penyebab suatu pola.
ggplot(usia_long, aes(x = Kelompok, y = Usia, fill = Kelompok)) +
geom_boxplot(alpha = 0.8, na.rm = TRUE) +
labs(title = "Perbandingan Sebaran Usia",
x = "Kelompok", y = "Usia (tahun)") +
theme_minimal() +
theme(legend.position = "none")
Boxplot merangkum median, rentang antarkuartil, dan nilai yang berpotensi ekstrem. Titik yang berada jauh dari sebaran utama perlu ditinjau, tetapi tidak selalu menunjukkan kesalahan pencatatan.
gender_korban <- data %>%
count(Victim.Gender.Clean, name = "Frekuensi") %>%
mutate(Persentase = round(Frekuensi / sum(Frekuensi) * 100, 2)) %>%
arrange(desc(Frekuensi))
gender_tersangka <- data %>%
count(Suspect.Gender.Clean, name = "Frekuensi") %>%
mutate(Persentase = round(Frekuensi / sum(Frekuensi) * 100, 2)) %>%
arrange(desc(Frekuensi))
kable(gender_korban, caption = "Distribusi gender korban")
| Victim.Gender.Clean | Frekuensi | Persentase |
|---|---|---|
| Male | 1824 | 34.75 |
| Female | 1683 | 32.06 |
| Unknown | 1382 | 26.33 |
| Other | 360 | 6.86 |
kable(gender_tersangka, caption = "Distribusi gender tersangka")
| Suspect.Gender.Clean | Frekuensi | Persentase |
|---|---|---|
| Unknown | 1735 | 33.05 |
| Female | 1645 | 31.34 |
| Male | 1554 | 29.61 |
| Other | 315 | 6.00 |
gender_long <- bind_rows(
data %>% count(Gender = Victim.Gender.Clean) %>% mutate(Kelompok = "Korban"),
data %>% count(Gender = Suspect.Gender.Clean) %>% mutate(Kelompok = "Tersangka")
)
ggplot(gender_long, aes(x = reorder(Gender, n), y = n, fill = Kelompok)) +
geom_col(position = "dodge") +
coord_flip() +
labs(title = "Frekuensi Gender Berdasarkan Kelompok",
x = "Gender", y = "Frekuensi", fill = "Kelompok") +
theme_minimal()
Tabulasi dan grafik gender digunakan untuk membandingkan frekuensi
kategori yang tercatat. Kategori Unknown atau nilai yang
belum diketahui tetap ditampilkan agar tingkat kelengkapan informasi
tidak tersembunyi.
kategori_kejahatan <- data %>%
count(Crime.Category, name = "Frekuensi", sort = TRUE) %>%
mutate(Persentase = round(Frekuensi / sum(Frekuensi) * 100, 2))
kable(kategori_kejahatan, caption = "Frekuensi kategori kejahatan")
| Crime.Category | Frekuensi | Persentase |
|---|---|---|
| Assault & Battery | 963 | 18.35 |
| Fraud & Scam | 457 | 8.71 |
| Arson | 369 | 7.03 |
| Drug Offense | 362 | 6.90 |
| Theft / Larceny | 348 | 6.63 |
| Kidnapping | 343 | 6.53 |
| Robbery | 334 | 6.36 |
| Burglary / B&E | 329 | 6.27 |
| Domestic Violence | 329 | 6.27 |
| Cybercrime | 318 | 6.06 |
| DUI / Drunk Driving | 307 | 5.85 |
| Homicide / Murder | 297 | 5.66 |
| Vandalism | 284 | 5.41 |
| Other | 122 | 2.32 |
| Property Damage | 49 | 0.93 |
| Sexual Assault | 38 | 0.72 |
ggplot(kategori_kejahatan,
aes(x = reorder(Crime.Category, Frekuensi), y = Frekuensi)) +
geom_col() +
coord_flip() +
labs(title = "Distribusi Kategori Kejahatan",
x = "Kategori kejahatan", y = "Jumlah catatan") +
theme_minimal()
Grafik kategori kejahatan membantu mengenali kategori yang paling sering dan paling jarang muncul dalam file kerja. Frekuensi ini merepresentasikan catatan pada dataset yang dianalisis, sehingga tidak dapat langsung dianggap sebagai tingkat kriminalitas populasi atau perbandingan risiko antarwilayah.
Encoding mengubah kategori menjadi bentuk yang dapat diproses oleh algoritma tertentu. Salah satu pendekatan yang digunakan dalam materi presentasi adalah One-Hot Encoding, yaitu membuat kolom indikator bernilai 0 atau 1 untuk setiap kategori.
data_encoding <- data %>%
mutate(
Victim.Gender.Clean = as.factor(Victim.Gender.Clean),
Suspect.Gender.Clean = as.factor(Suspect.Gender.Clean),
Crime.Category = as.factor(Crime.Category)
)
dummy_gender <- model.matrix(~ Victim.Gender.Clean - 1, data = data_encoding)
head(dummy_gender, 6) %>%
as.data.frame() %>%
kable(caption = "Contoh hasil One-Hot Encoding gender korban")
| Victim.Gender.CleanFemale | Victim.Gender.CleanMale | Victim.Gender.CleanOther | Victim.Gender.CleanUnknown |
|---|---|---|---|
| 0 | 0 | 0 | 1 |
| 0 | 0 | 0 | 1 |
| 0 | 0 | 1 | 0 |
| 0 | 0 | 0 | 1 |
| 0 | 1 | 0 | 0 |
| 0 | 0 | 0 | 1 |
Variabel hasil encoding dapat digunakan dalam proses pemodelan yang membutuhkan masukan numerik. Kategori tetap perlu ditafsirkan berdasarkan label aslinya. Pengubahan kategori menjadi angka tidak berarti bahwa kategori tersebut memiliki tingkatan atau jarak numerik.
Z-Score menyatakan jarak suatu pengamatan dari rata-rata dalam satuan simpangan baku. Rumus yang digunakan adalah:
\[ Z = \frac{X-\bar{X}}{s} \]
dengan \(X\) sebagai nilai pengamatan, \(\bar{X}\) sebagai rata-rata sampel, dan \(s\) sebagai simpangan baku sampel.
data_transformasi <- data %>%
mutate(
Victim_Age_Z = as.numeric(scale(Victim.Age.Clean)),
Suspect_Age_Z = as.numeric(scale(Suspect.Age.Clean))
)
data_transformasi %>%
select(Victim.Age.Clean, Suspect.Age.Clean, Victim_Age_Z, Suspect_Age_Z) %>%
head(10) %>%
mutate(across(where(is.numeric), ~round(.x, 3))) %>%
kable(caption = "Contoh hasil standardisasi Z-Score")
| Victim.Age.Clean | Suspect.Age.Clean | Victim_Age_Z | Suspect_Age_Z |
|---|---|---|---|
| 51 | 51 | 0.053 | 0.368 |
| 50 | 46 | 0.005 | 0.032 |
| 29 | 19 | -0.993 | -1.784 |
| 50 | 46 | 0.005 | 0.032 |
| 51 | 75 | 0.053 | 1.982 |
| 15 | 73 | -1.659 | 1.847 |
| 72 | 58 | 1.051 | 0.839 |
| 50 | 73 | 0.005 | 1.847 |
| 55 | 26 | 0.243 | -1.313 |
| 10 | 46 | -1.896 | 0.032 |
Setelah standardisasi, usia korban dan tersangka dinyatakan relatif terhadap rata-rata dan simpangan baku masing-masing variabel. Nilai Z positif menunjukkan usia di atas rata-rata kelompok variabelnya, sedangkan nilai negatif menunjukkan usia di bawah rata-rata. Karena standardisasi dilakukan secara terpisah, Z-Score sesuai untuk membandingkan posisi relatif dalam distribusi masing-masing, bukan menyimpulkan bahwa perbedaan usia mentah telah hilang.
z_long <- data_transformasi %>%
select(Victim_Age_Z, Suspect_Age_Z) %>%
pivot_longer(cols = everything(), names_to = "Kelompok", values_to = "Z_Score") %>%
mutate(Kelompok = recode(Kelompok,
Victim_Age_Z = "Korban",
Suspect_Age_Z = "Tersangka")) %>%
filter(is.finite(Z_Score))
ggplot(z_long, aes(x = Z_Score, fill = Kelompok)) +
geom_histogram(binwidth = 0.5, color = "white", alpha = 0.85) +
facet_wrap(~Kelompok, ncol = 1) +
labs(title = "Distribusi Usia Setelah Standardisasi Z-Score",
x = "Z-Score", y = "Frekuensi") +
theme_minimal() +
theme(legend.position = "none")
Eksplorasi data menyediakan gambaran awal tentang kelengkapan data, sebaran usia, komposisi gender, dan kategori kejahatan yang tercatat. Ringkasan statistik dan grafik saling melengkapi: tabel menyajikan nilai secara terukur, sedangkan visualisasi memudahkan pengamatan pola, perbedaan sebaran, dan kemungkinan nilai ekstrem.
Tahapan pembersihan yang dijelaskan dalam presentasi mencakup penanganan nilai hilang, penyeragaman kategori, pemeriksaan nilai numerik yang tidak masuk akal, validasi koordinat, dan penyeragaman format tanggal. Namun, file Excel yang dianalisis pada artikel ini hanya memuat 10 variabel demografi dan kategori kejahatan. Oleh sebab itu, pemeriksaan koordinat, tren waktu, kerugian properti, penggunaan senjata, serta evaluasi penegakan hukum tidak dapat dihitung ulang dari file kerja ini.
Materi presentasi juga mencantumkan hasil uji diagnostik, yaitu uji normalitas residual dengan p-value yang dilaporkan sebesar \(2.2 \times 10^{-16}\), uji heteroskedastisitas dengan p-value 0,6697, serta uji Levene dengan p-value 0,00001578. Hasil tersebut merupakan hasil yang dilaporkan pada presentasi dan tidak direproduksi dalam artikel ini, karena file Excel yang tersedia tidak menyertakan variabel dan spesifikasi model yang diperlukan untuk mengulang pengujian tersebut. Interpretasi uji diagnostik harus selalu mengacu pada model dan prosedur pengujian yang digunakan.
Secara metodologis, hasil eksplorasi tidak membuktikan hubungan sebab-akibat antara demografi dan kejadian kriminalitas. Data juga dapat dipengaruhi oleh proses pelaporan, kelengkapan pencatatan, serta aturan pengelompokan. Dengan demikian, temuan perlu dibaca sebagai deskripsi dataset yang tersedia dan bukan generalisasi terhadap seluruh kejadian kriminalitas.
Analisis data eksploratif merupakan proses sistematis untuk memahami struktur dan kualitas data sebelum digunakan dalam analisis lanjutan. Berdasarkan file kerja Kelompok 3, eksplorasi dapat dilakukan pada variabel usia korban dan tersangka, gender, serta kategori kejahatan. Pemeriksaan nilai hilang dan kewajaran usia menjadi bagian penting untuk menjaga kehati-hatian interpretasi.
Transformasi One-Hot Encoding mengubah variabel kategorik menjadi indikator numerik, sedangkan Z-Score menempatkan usia pada skala relatif terhadap rata-rata dan simpangan baku masing-masing kelompok variabel. Kedua transformasi tersebut mendukung kesiapan data untuk analisis berikutnya, tetapi tidak menggantikan kebutuhan memahami konteks dan kualitas data.
Analisis lanjutan akan lebih kuat apabila tersedia dataset lengkap beserta definisi variabel, asal-usul pencatatan, dan dokumentasi proses pembersihan. Pemeriksaan kembali terhadap sumber asli diperlukan untuk memastikan nilai anomali dan kategori yang belum diketahui ditangani secara tepat.
Dokumen ini disusun dalam format R Markdown agar kode, tabel, grafik,
dan narasi dapat diperbarui secara konsisten. Untuk menghasilkan
laporan, letakkan file Excel di folder yang sama, buka dokumen
.Rmd di RStudio, lalu pilih Knit. Pastikan
paket yang digunakan telah terpasang:
install.packages(c("rmarkdown", "readxl", "dplyr", "tidyr", "ggplot2", "knitr"))