UTS_Pemrograman Sains Data
1 Data Collection
Pada tahap ini, data dibaca dari berbagai format file seperti CSV, Excel, JSON, dan TXT menggunakan perulangan (loop) dan kondisi (if).
1.1 Informasi Setiap File
Setiap file ditampilkan jumlah baris, jumlah kolom, dan nama kolom untuk memastikan kesesuaian struktur data
library(readxl)
library(jsonlite)
files <- list.files()
data_list <- list()
for (file in files) {
if (grepl(".csv$", file)) {
data <- read.csv(file)
} else if (grepl(".xlsx$", file)) {
data <- read_excel(file)
} else if (grepl(".json$", file)) {
data <- fromJSON(file)
} else if (grepl(".txt$", file)) {
data <- read.csv(file)
} else {
next
}
data_list[[file]] <- data
}library(kableExtra)
info_list <- data.frame(
File = character(),
Jumlah_Baris = numeric(),
Jumlah_Kolom = numeric(),
stringsAsFactors = FALSE
)
for (file in names(data_list)) {
df <- data_list[[file]]
info_list <- rbind(info_list, data.frame(
File = file,
Jumlah_Baris = nrow(df),
Jumlah_Kolom = ncol(df)
))
}
knitr::kable(info_list, align = "c") %>%
kable_styling(
full_width = TRUE # ⬅️ bikin lebar full halaman
) %>%
row_spec(0, bold = TRUE, background = "#8B1E3F", color = "white") %>%
row_spec(1:nrow(info_list), background = "#F9F9F9") %>%
column_spec(1, bold = TRUE, width = "40%") %>%
column_spec(2:3, width = "30%")| File | Jumlah_Baris | Jumlah_Kolom |
|---|---|---|
| ecommerce.csv | 2000 | 22 |
| ecommerce.json | 2000 | 22 |
| ecommerce.txt | 2000 | 1 |
| ecommerce.xlsx | 2000 | 22 |
library(kableExtra)
status_list <- data.frame(
File = names(data_list),
Status = ifelse(
sapply(data_list, ncol) == 22,
"✅ Ready to merge",
"⚠️ Need adjustment"
)
)
knitr::kable(status_list, align = "c", escape = FALSE, row.names = FALSE) %>%
kable_styling(full_width = TRUE) %>%
row_spec(0, bold = TRUE, background = "#8B1E3F", color = "white") %>%
row_spec(1:nrow(status_list), background = "#F9F9F9") %>%
column_spec(1, bold = TRUE, width = "50%") %>%
column_spec(2, width = "50%")| File | Status |
|---|---|
| ecommerce.csv | ✅ Ready to merge | |
| ecommerce.json | ✅ Ready to merge | |
| ecommerce.txt | ⚠️ Need adjustment |
| ecommerce.xlsx | ✅ Ready to merge | |
1.2 Penggabungan Data
Data yang memiliki struktur kolom yang sama digabungkan menjadi satu dataset utama menggunakan fungsi rbind.
library(kableExtra)
# filter data yang siap merge (22 kolom)
data_ready <- data_list[sapply(data_list, ncol) == 22]
# gabungkan
final_data <- do.call(rbind, data_ready)
# tampilkan hasil
knitr::kable(
data.frame(
Total_Baris = nrow(final_data),
Total_Kolom = ncol(final_data)
),
align = "c",
row.names = FALSE
) %>%
kable_styling(full_width = TRUE) %>%
row_spec(0, bold = TRUE, background = "#8B1E3F", color = "white") %>%
row_spec(1, background = "#F9F9F9")| Total_Baris | Total_Kolom |
|---|---|
| 6000 | 22 |
Dataset utama yang dihasilkan terdiri dari 6000 baris dan 22 kolom, yang berasal dari penggabungan file dengan struktur kolom yang sama, sementara file dengan struktur berbeda tidak disertakan.
2 Data Handling
Pada tahap ini dilakukan analisis terhadap dataset hasil penggabungan untuk memahami struktur data, tipe data, serta mengidentifikasi potensi masalah seperti missing values dan data duplikat.
2.1 Informasi Dataset
Menampilkan jumlah total baris, jumlah kolom, dan tipe data dari setiap kolom pada dataset utama.
library(kableExtra)
# ukuran dataset
info_dataset <- data.frame(
Total_Baris = nrow(final_data),
Total_Kolom = ncol(final_data)
)
knitr::kable(info_dataset, align = "c", row.names = FALSE) %>%
kable_styling(full_width = TRUE) %>%
row_spec(0, bold = TRUE, background = "#8B1E3F", color = "white") %>%
row_spec(1, background = "#F9F9F9")| Total_Baris | Total_Kolom |
|---|---|
| 6000 | 22 |
tipe_data <- data.frame(
Kolom = names(final_data),
Tipe_Data = sapply(final_data, class)
)
knitr::kable(tipe_data, align = "c", row.names = FALSE) %>%
kable_styling(full_width = TRUE) %>%
row_spec(0, bold = TRUE, background = "#8B1E3F", color = "white") %>%
row_spec(1:nrow(tipe_data), background = "#F9F9F9")| Kolom | Tipe_Data |
|---|---|
| order_id | character |
| order_date | character |
| ship_date | character |
| platform | character |
| category | character |
| product_name | character |
| unit_price | character |
| quantity | character |
| gross_sales | character |
| campaign | character |
| voucher_code | character |
| discount_pct | character |
| discount_value | character |
| shipping_cost | numeric |
| net_sales | character |
| payment_method | character |
| customer_segment | character |
| region | character |
| stock_status | character |
| order_status | character |
| customer_rating | character |
| priority_flag | character |
2.2 Identifikasi Masalah Data
Dilakukan identifikasi terhadap missing values dan data duplikat untuk mengetahui kualitas dataset.
missing_data <- colSums(is.na(final_data))
missing_df <- data.frame(
Kolom = names(missing_data),
Jumlah_Missing = missing_data
)
knitr::kable(missing_df, align = "c", row.names = FALSE) %>%
kable_styling(full_width = TRUE) %>%
row_spec(0, bold = TRUE, background = "#8B1E3F", color = "white") %>%
row_spec(1:nrow(missing_df), background = "#F9F9F9")| Kolom | Jumlah_Missing |
|---|---|
| order_id | 0 |
| order_date | 0 |
| ship_date | 251 |
| platform | 0 |
| category | 0 |
| product_name | 0 |
| unit_price | 0 |
| quantity | 0 |
| gross_sales | 0 |
| campaign | 0 |
| voucher_code | 98 |
| discount_pct | 207 |
| discount_value | 0 |
| shipping_cost | 0 |
| net_sales | 0 |
| payment_method | 70 |
| customer_segment | 0 |
| region | 0 |
| stock_status | 0 |
| order_status | 0 |
| customer_rating | 1208 |
| priority_flag | 376 |
Jumlah missing values yang cukup tinggi ditemukan pada kolom customer_rating (1208 data), ship_date (251 data), dan priority_flag (376 data). Hal ini menunjukkan adanya ketidaklengkapan data yang signifikan dan perlu dilakukan penanganan agar tidak mempengaruhi hasil analisis.
jumlah_duplikat <- sum(duplicated(final_data))
knitr::kable(
data.frame(Jumlah_Duplikat = jumlah_duplikat),
align = "c",
row.names = FALSE
) %>%
kable_styling(full_width = TRUE) %>%
row_spec(0, bold = TRUE, background = "#8B1E3F", color = "white") %>%
row_spec(1, background = "#F9F9F9")| Jumlah_Duplikat |
|---|
| 3231 |
Jumlah data duplikat yang cukup tinggi yaitu sebanyak 3231 baris menunjukkan adanya redundansi data yang berpotensi mempengaruhi akurasi hasil analisis, sehingga diperlukan proses pembersihan data.
2.3 Identifikasi Masalah Kualitas Data
Berdasarkan hasil analisis, ditemukan beberapa masalah kualitas data, antara lain:
- Terdapat missing values pada beberapa kolom yang perlu ditangani.
- Ditemukan data duplikat yang dapat mempengaruhi hasil analisis.
- Perbedaan tipe data pada beberapa kolom yang berpotensi menyebabkan inkonsistensi dalam pengolahan data.
3 Data Cleaning
Pada tahap ini dilakukan pembersihan data menggunakan logika pemrograman seperti kondisi (if) dan perulangan (loop) untuk memastikan konsistensi dan kualitas data.
3.1 Standardisasi Platform
Dilakukan standarisasi penulisan nama platform agar konsisten, seperti “shopee”, “SHOPEE” menjadi “Shopee” dan “tokped” menjadi “Tokopedia”.
final_data$platform <- tolower(trimws(final_data$platform))
final_data$platform[grepl("shopee", final_data$platform)] <- "Shopee"
final_data$platform[grepl("tokopedia|tokped", final_data$platform)] <- "Tokopedia"
final_data$platform[grepl("lazada", final_data$platform)] <- "Lazada"
final_data$platform[grepl("blibli", final_data$platform)] <- "Blibli"
final_data$platform[grepl("tiktok", final_data$platform)] <- "TikTok Shop"platform_table <- as.data.frame(table(final_data$platform))
colnames(platform_table) <- c("Platform", "Jumlah")
platform_table <- platform_table[order(-platform_table$Jumlah), ]
knitr::kable(
platform_table,
align = "c",
row.names = FALSE
) %>%
kableExtra::kable_styling(full_width = TRUE) %>%
kableExtra::row_spec(0, bold = TRUE, background = "#8B1E3F", color = "white") %>%
kableExtra::row_spec(1:nrow(platform_table), background = "#F9F9F9")| Platform | Jumlah |
|---|---|
| Shopee | 1248 |
| TikTok Shop | 1218 |
| Blibli | 1212 |
| Lazada | 1164 |
| Tokopedia | 1158 |
Setelah dilakukan standarisasi, jumlah kategori platform berhasil disederhanakan menjadi 5 kategori utama. Hal ini menunjukkan bahwa sebelumnya terdapat inkonsistensi penulisan yang menyebabkan data terfragmentasi.
3.2 Cleaning Harga
Dilakukan pembersihan pada kolom harga dan penjualan dengan mengubah format mata uang seperti “Rp xxx.xxx” menjadi numerik, serta menangani nilai negatif dengan mengubahnya menjadi 0 agar data lebih valid untuk analisis.
# Kolom yang akan dibersihkan
cols_price <- c("unit_price", "gross_sales", "discount_value", "net_sales")
for (col in cols_price) {
# Hapus "Rp", titik, dan ubah ke numeric
final_data[[col]] <- as.numeric(
gsub("[^0-9]", "", final_data[[col]])
)
# Jika nilai negatif → jadi 0
final_data[[col]][final_data[[col]] < 0] <- 0
}price_check <- data.frame(
Kolom = cols_price,
Min = sapply(final_data[cols_price], min, na.rm = TRUE),
Max = sapply(final_data[cols_price], max, na.rm = TRUE)
)
knitr::kable(
price_check,
align = "c",
row.names = FALSE
) %>%
kableExtra::kable_styling(full_width = TRUE) %>%
kableExtra::row_spec(0, bold = TRUE, background = "#8B1E3F", color = "white") %>%
kableExtra::row_spec(1:nrow(price_check), background = "#F9F9F9")| Kolom | Min | Max |
|---|---|---|
| unit_price | 30827 | 2498385 |
| gross_sales | 31646 | 22642020 |
| discount_value | 0 | 6792606 |
| net_sales | 0 | 18080224 |
Setelah proses cleaning, seluruh kolom harga berhasil dikonversi menjadi numerik dan tidak ditemukan lagi nilai negatif. Hal ini menunjukkan bahwa data telah siap digunakan untuk analisis lebih lanjut tanpa adanya distorsi akibat format atau nilai yang tidak valid. Selain itu, rentang nilai minimum dan maksimum menunjukkan bahwa data berada dalam skala yang wajar dan siap digunakan untuk analisis lebih lanjut. Nilai 0 pada beberapa kolom menunjukkan hasil dari penanganan nilai negatif atau memang tidak adanya diskon pada transaksi tertentu.
3.3 Missing Value
Dilakukan penanganan missing values pada beberapa kolom dengan
menggunakan kondisi (if). Kolom payment_method yang kosong
diisi dengan “Unknown”, sedangkan kolom customer_rating
yang memiliki nilai kosong diisi dengan nilai default berupa rata-rata
(mean) dari kolom tersebut.
| Kolom | Sisa_Missing |
|---|---|
| order_id | 0 |
| order_date | 0 |
| ship_date | 251 |
| platform | 0 |
| category | 0 |
| product_name | 0 |
| unit_price | 0 |
| quantity | 0 |
| gross_sales | 0 |
| campaign | 0 |
| voucher_code | 98 |
| discount_pct | 207 |
| discount_value | 0 |
| shipping_cost | 0 |
| net_sales | 0 |
| payment_method | 0 |
| customer_segment | 0 |
| region | 0 |
| stock_status | 0 |
| order_status | 0 |
| customer_rating | 1208 |
| priority_flag | 376 |
Setelah dilakukan penanganan missing values, tidak ditemukan lagi
nilai kosong pada kolom yang dianalisis. Kolom
payment_method berhasil diisi dengan kategori “Unknown”,
sedangkan kolom customer_rating diisi menggunakan nilai
rata-rata sehingga tetap menjaga distribusi data. Hal ini membuat
dataset menjadi lebih lengkap dan siap digunakan untuk analisis
lanjutan.
3.4 Standardisasi Order Status
Dilakukan standarisasi pada kolom order_status untuk
memastikan konsistensi penulisan data. Beberapa variasi penulisan
seperti “delivered” dan “cancelled” diubah menjadi format yang seragam
yaitu “Completed” dan “Cancelled” menggunakan kondisi (if).
| Order_Status | Jumlah |
|---|---|
| batal | 12 |
| cancelled | 4 |
| completed | 28 |
| delivered | 50 |
| on delivery | 4 |
| retur | 4 |
| returned | 6 |
| shipped | 2 |
| batal | 87 |
| cancel | 108 |
| Cancelled | 245 |
| completed | 1172 |
| Completed | 3490 |
| on delivery | 140 |
| retur | 125 |
| returned | 219 |
| shipped | 304 |
Setelah dilakukan standarisasi, nilai pada kolom
order_status menjadi lebih konsisten dengan hanya memiliki
kategori utama yaitu “Completed” dan “Cancelled”. Hal ini menghindari
inkonsistensi data akibat perbedaan penulisan dan mempermudah analisis
lebih lanjut.
3.5 Penerapan Looping dalam Data Cleaning
Dilakukan proses pembersihan data menggunakan teknik looping (perulangan) untuk membersihkan beberapa kolom sekaligus. Kolom yang dibersihkan meliputi kolom numerik seperti unit_price, gross_sales, discount_value, dan net_sales dengan memastikan format data sudah berupa numerik dan tidak mengandung nilai negatif.
| Kolom | Min | Max |
|---|---|---|
| unit_price | 30827 | 2498385 |
| gross_sales | 31646 | 22642020 |
| discount_value | 0 | 6792606 |
| net_sales | 0 | 18080224 |
Dengan menggunakan looping, proses pembersihan data dapat dilakukan secara efisien pada beberapa kolom sekaligus. Seluruh kolom numerik telah berhasil dikonversi ke tipe numerik dan tidak ditemukan lagi nilai negatif. Hal ini menunjukkan bahwa teknik looping sangat efektif dalam meningkatkan efisiensi dan konsistensi proses data cleaning. Proses ini juga meminimalkan redundansi kode dengan menerapkan pembersihan secara terstruktur menggunakan perulangan.
4 Conditional Logic
Pada tahap ini diterapkan logika bisnis menggunakan kondisi if dan if-else untuk membuat variabel baru berdasarkan aturan tertentu. Proses ini bertujuan untuk mengklasifikasikan data agar lebih mudah dianalisis, seperti mengidentifikasi transaksi bernilai tinggi, menentukan prioritas pesanan, serta memvalidasi status transaksi. Dengan penerapan conditional logic, dataset menjadi lebih informatif dan mampu merepresentasikan kondisi bisnis secara lebih jelas.
4.1 is_high_value
Dilakukan pembuatan kolom baru is_high_value untuk
mengidentifikasi transaksi dengan nilai tinggi. Jika nilai
net_sales lebih dari 1.000.000 maka dikategorikan sebagai
“Yes”, dan selain itu dikategorikan sebagai “No” menggunakan kondisi
if.
| Kategori | Jumlah |
|---|---|
| No | 3543 |
| Yes | 2457 |
Hasil klasifikasi menunjukkan bahwa sebagian transaksi memiliki nilai penjualan di atas 1.000.000 dan dikategorikan sebagai transaksi bernilai tinggi. Klasifikasi ini membantu dalam mengidentifikasi kontribusi transaksi besar terhadap total pendapatan serta mendukung analisis segmentasi penjualan.
4.2 order_priority
Dilakukan pembuatan kolom baru order_priority untuk
mengelompokkan prioritas pesanan berdasarkan nilai
net_sales. Klasifikasi dilakukan menggunakan nested if,
dimana nilai di atas 1.000.000 dikategorikan sebagai “High”, nilai
antara 500.000 hingga 1.000.000 sebagai “Medium”, dan nilai di bawah
500.000 sebagai “Low”.
| Prioritas | Jumlah |
|---|---|
| High | 2457 |
| Medium | 1353 |
| Low | 2190 |
Hasil pengelompokan menunjukkan bahwa transaksi terbagi ke dalam tiga kategori prioritas, yaitu High, Medium, dan Low. Klasifikasi ini membantu dalam memahami distribusi nilai transaksi serta mempermudah penentuan strategi bisnis berdasarkan tingkat prioritas pesanan.
4.3 valid_transaction
Dilakukan pembuatan kolom baru valid_transaction untuk
mengidentifikasi validitas transaksi berdasarkan status pesanan. Jika
nilai order_status adalah “Cancelled” maka transaksi
dikategorikan sebagai “Invalid”, sedangkan selain itu dikategorikan
sebagai “Valid” menggunakan kondisi if.
| Status | Jumlah |
|---|---|
| Valid | 5755 |
| Invalid | 245 |
Hasil klasifikasi menunjukkan bahwa sebagian besar transaksi termasuk dalam kategori valid (5755 data), sedangkan sebagian kecil transaksi tidak valid (245 data) akibat status pesanan yang dibatalkan. Dengan adanya identifikasi ini, proses analisis selanjutnya dapat difokuskan pada transaksi yang valid sehingga menghasilkan informasi yang lebih akurat dan relevan.
5 Analytical Thinking
Platform yang paling dominan adalah Shopee, karena memiliki jumlah transaksi tertinggi dibandingkan platform lainnya. Hal ini menunjukkan bahwa Shopee menjadi platform utama dalam dataset dan memberikan kontribusi terbesar terhadap total penjualan.
Kategori yang paling sering muncul adalah Fashion. Namun, ditemukan adanya inkonsistensi penulisan kategori seperti “Fashion”, “FASHION”, dan “fashion” yang sebenarnya merepresentasikan kategori yang sama. Hal ini menunjukkan bahwa sebelum proses cleaning, data kategori masih belum terstandarisasi dengan baik.
Status transaksi yang paling banyak adalah Valid, dengan jumlah yang jauh lebih tinggi dibandingkan transaksi Invalid. Hal ini menunjukkan bahwa sebagian besar transaksi berhasil diproses dengan baik sehingga dataset cukup reliabel untuk analisis lebih lanjut.
Secara keseluruhan, data menunjukkan bahwa transaksi didominasi oleh platform Shopee dengan kategori produk yang paling banyak adalah Fashion. Meskipun demikian, terdapat inkonsistensi pada penulisan kategori yang menegaskan pentingnya proses data cleaning sebelum analisis dilakukan. Selain itu, mayoritas transaksi berada dalam kondisi valid, sehingga dataset dapat digunakan untuk analisis bisnis lanjutan seperti analisis penjualan dan segmentasi pelanggan.