Kemajuan teknologi digital membuka peluang besar bagi masyarakat untuk bekerja secara bebas (freelance) tanpa terikat oleh lokasi atau kantor tertentu. Di pasar kerja digital ini, para freelancer memiliki latar belakang yang sangat beragam, mulai dari rentang usia, bidang keahlian, jam terbang pengalaman, hingga tarif jasa yang mereka tetapkan. Dari berbagai faktor tersebut, lama pengalaman kerja menjadi aspek yang sangat menarik untuk dicermati karena dinilai berhubungan erat dengan tingginya tarif per jam (hourly rate) yang ditawarkan.
Untuk menguji hal tersebut, analisis ini memanfaatkan Global Freelancers Dataset yang diperoleh dari platform Kaggle. Dataset ini mencakup 1.000 data freelancer dengan 12 variabel informasi, seperti profil individu, tingkat pengalaman, tarif jasa, penilaian (rating), tingkat kepuasan klien, hingga status keaktifan mereka di platform.
Sebelum masuk ke tahap analisis utama, seluruh data diperiksa terlebih dahulu secara teliti. Langkah pemeriksaan ini bertujuan untuk mendeteksi serta menangani potensi masalah, seperti adanya data yang kosong (missing value), pengkategorian yang tidak konsisten, kesalahan format penulisan, data ganda (duplikasi), maupun nilai ekstrem yang tidak wajar. Setelah data dibersihkan dan siap digunakan, analisis dilakukan untuk menggambarkan profil pengalaman kerja para freelancer sekaligus melihat seberapa besar pengaruhnya terhadap penentuan tarif per jam mereka.
Mengidentifikasi berbagai permasalahan kualitas data pada Global Freelancers Dataset.
Melakukan proses data cleaning dan preprocessing untuk menangani nilai yang hilang, menghapus duplikasi, serta menyeragamkan format variabel kategorikal maupun numerik.
Menganalisis karakteristik dan sebaran pengalaman kerja freelancer melalui pengodean kategori (encoding) serta statistik deskriptif.
Mengkaji arah dan pola hubungan antara pengalaman kerja dengan tarif per jam (hourly rate) yang ditetapkan oleh freelancer.
Memeriksa pemenuhan uji asumsi statistik (uji normalitas Shapiro-Wilk dan uji homogenitas varians Bartlett) serta menerapkan transformasi numerik yang sesuai untuk analisis lanjutan.
Dataset yang dianalisis dalam penelitian ini merupakan Global Freelancers Raw Dataset yang dibuat oleh Urvish Ahir dan diunggah ke platform Kaggle pada tahun 2024. Data ini berskala global dan mencakup informasi mengenai profil pekerja lepas digital dari berbagai negara, seperti atribut keahlian, tarif per jam, rating, serta aspek demografis lainnya. Dataset ini dikembangkan secara sintetis menggunakan bahasa pemrograman Python dengan pustaka tertentu, yang ditujukan sebagai bahan pemelajaran pembersihan data (data cleaning) dan analisis eksploratif (EDA). Seluruh informasi tersimpan dalam format berkas Excel, di mana setiap baris mewakili satu individu freelancer sebagai unit observasinya.
Dataset Global Freelancers Raw Dataset memuat sebanyak 1.000 baris data observasi freelancer yang terbagi ke dalam 12 variabel informasi utama. Informasi tersebut mencakup aspek demografi dan identitas individu (seperti ID freelancer, nama, jenis kelamin, usia, negara asal, dan bahasa yang digunakan), karakteristik profesionalitas (meliputi bidang keahlian utama dan lama pengalaman kerja dalam hitungan tahun), serta indikator kinerja dan finansial (terdiri dari tarif jasa per jam dalam satuan USD, rating, status keaktifan akun, dan tingkat kepuasan klien). Karena dataset ini masih berupa data mentah, beberapa variabel masih memiliki nilai yang hilang (missing values) dan format penulisan yang belum seragam, sehingga memerlukan tahapan pembersihan data (data cleaning) terlebih dahulu sebelum dapat dianalisis secara akurat.
Data dalam penelitian ini berasal dari Global Freelancers Raw
Dataset yang diambil dari platform Kaggle dengan nama file
data ade global_freelancers_raw.xlsx.
Dataset ini dikelompokkan ke dalam dua jenis data utama, yaitu data kualitatif (kategori) dan data kuantitatif (angka). Data kualitatif terdiri atas identitas unik seperti ID_freelancer dan nama, serta variabel kategorikal seperti jenis kelamin, negara asal, bahasa utama, bidang keahlian utama, dan status keaktifan akun. Sementara itu, data kuantitatif mencakup variabel numerik diskret berupa usia dan lama pengalaman kerja dalam hitungan tahun, serta variabel numerik kontinu berupa tarif per jam dalam satuan USD, rating kinerja, dan tingkat kepuasan klien.
Langkah pertama dalam proses pengolahan data ini adalah melakukan import data, yaitu memuat berkas Global Freelancers Raw Dataset ke dalam sistem R serta menjalankan fungsi evaluasi awal untuk memeriksa dimensi, struktur, sampel data, dan ringkasan statistik deskriptifnya melalui sintaks berikut:
library(readxl)
ADE<- read_excel("D:\\Semester 3\\data ade global_freelancers_raw.xlsx")
cat("Jumlah baris dan kolom:", dim(ADE), "\n")## Jumlah baris dan kolom: 1000 12
## tibble [1,000 × 12] (S3: tbl_df/tbl/data.frame)
## $ freelancer_ID : chr [1:1000] "FL250001" "FL250002" "FL250003" "FL250004" ...
## $ name : chr [1:1000] "Ms. Nicole Kidd" "Vanessa Garcia" "Juan Nelson" "Amanda Spencer" ...
## $ gender : chr [1:1000] "f" "FEMALE" "male" "F" ...
## $ age : chr [1:1000] "52.0" "52.0" "53.0" "38.0" ...
## $ country : chr [1:1000] "Italy" "Australia" "Germany" "Australia" ...
## $ language : chr [1:1000] "Italian" "English" "German" "English" ...
## $ primary_skill : chr [1:1000] "Blockchain Development" "Mobile Apps" "Graphic Design" "Web Development" ...
## $ years_of_experience: chr [1:1000] "11.0" "34.0" "31.0" "4.0" ...
## $ hourly_rate (USD) : chr [1:1000] "100" "USD 100" "50" "$40" ...
## $ rating : chr [1:1000] NA "3.3" "0.0" "1.5" ...
## $ is_active : chr [1:1000] "0" "1" "N" "N" ...
## $ client_satisfaction: num [1:1000] NA 0.84 0.71 0.9 0.83 NA 0.94 0.94 0.76 NA ...
## # A tibble: 6 × 12
## freelancer_ID name gender age country language primary_skill
## <chr> <chr> <chr> <chr> <chr> <chr> <chr>
## 1 FL250001 Ms. Nicole Kidd f 52.0 Italy Italian Blockchain De…
## 2 FL250002 Vanessa Garcia FEMALE 52.0 Australia English Mobile Apps
## 3 FL250003 Juan Nelson male 53.0 Germany German Graphic Design
## 4 FL250004 Amanda Spencer F 38.0 Australia English Web Developme…
## 5 FL250005 Lynn Curtis DDS female 53.0 Germany German Web Developme…
## 6 FL250006 Lisa Johnson female 59.0 Netherlands Dutch AI
## # ℹ 5 more variables: years_of_experience <chr>, `hourly_rate (USD)` <chr>,
## # rating <chr>, is_active <chr>, client_satisfaction <dbl>
## freelancer_ID name gender age
## Length:1000 Length:1000 Length:1000 Length:1000
## Class :character Class :character Class :character Class :character
## Mode :character Mode :character Mode :character Mode :character
##
##
##
##
## country language primary_skill years_of_experience
## Length:1000 Length:1000 Length:1000 Length:1000
## Class :character Class :character Class :character Class :character
## Mode :character Mode :character Mode :character Mode :character
##
##
##
##
## hourly_rate (USD) rating is_active client_satisfaction
## Length:1000 Length:1000 Length:1000 Min. : 0.60
## Class :character Class :character Class :character 1st Qu.: 0.71
## Mode :character Mode :character Mode :character Median : 0.82
## Mean : 11.73
## 3rd Qu.: 0.94
## Max. :100.00
## NA's :176
Berdasarkan output dari sintaks di atas, dapat diketahui bahwa dataset memuat 1.000 baris data dan 12 kolom variabel. Hasil pemeriksaan awal ini juga menunjukkan adanya nilai yang hilang (missing values) serta ketidakseragaman format pada beberapa variabel (seperti tarif per jam dan status keaktifan), sehingga data memerlukan pembersihan lebih lanjut sebelum dianalisis.
Sebelum masuk ke tahap pembersihan data, perlu dilakukan pemetaan terlebih dahulu terhadap berbagai masalah kualitas data yang ditemukan dalam dataset. Berdasarkan hasil pemeriksaan awal, teridentifikasi sejumlah permasalahan utama yang dikelompokkan ke dalam beberapa aspek berikut.
Salah satu permasalahan utama yang ditemukan pada dataset ini adalah ketersediaan data yang tidak lengkap atau adanya nilai yang hilang (missing value). Untuk mengetahui sebaran serta proporsi data yang kosong pada masing-masing variabel, dilakukan penghitungan jumlah dan persentase missing value.
banyak_missing <- colSums(is.na(ADE))
persentase_missing <- round(
colMeans(is.na(ADE)) * 100,
2
)
tabel_missing <- data.frame(
Variabel = names(banyak_missing),
Jumlah_Missing = as.integer(banyak_missing),
Persentase_Missing = as.numeric(persentase_missing)
)
tabel_missing## Variabel Jumlah_Missing Persentase_Missing
## 1 freelancer_ID 0 0.0
## 2 name 0 0.0
## 3 gender 0 0.0
## 4 age 30 3.0
## 5 country 0 0.0
## 6 language 0 0.0
## 7 primary_skill 0 0.0
## 8 years_of_experience 51 5.1
## 9 hourly_rate (USD) 94 9.4
## 10 rating 101 10.1
## 11 is_active 89 8.9
## 12 client_satisfaction 176 17.6
## Total missing value: 541
Berdasarkan hasil keluaran dari sintaks di atas, secara keseluruhan terdapat 541 data kosong (missing value) yang tersebar pada 6 variabel berbeda. Variabel dengan tingkat kemunculan data kosong tertinggi adalah client_satisfaction sebesar 17,6% (176 data), diikuti oleh rating sebesar 10,1% (101 data), hourly_rate (USD) sebesar 9,4% (94 data), is_active sebesar 8,9% (89 data), years_of_experience sebesar 5,1% (51 data), dan age sebesar 3,0% (30 data). Keberadaan data kosong ini memerlukan penanganan khusus, baik melalui penghapusan observasi maupun imputasi data, agar tidak mengganggu hasil analisis.
Permasalahan berikutnya yang ditemukan dalam dataset ini adalah inkonsistensi penulisan kategori pada beberapa variabel kualitatif. Ketidakseragaman format seperti perbedaan penggunaan huruf kapital, singkatan, maupun variasi nilai kategorikal dapat menyebabkan data terpisah ke dalam kelompok yang salah. Untuk mengidentifikasi bentuk-bentuk inkonsistensi tersebut, dilakukan pemeriksaan frekuensi nilai pada variabel gender dan is_active menggunakan sintaks R berikut:
##
## f F female Female FEMALE m M male Male MALE
## 103 90 86 96 115 99 106 100 103 102
##
## 0 1 FALSE N no TRUE Y yes <NA>
## 182 190 97 98 88 77 94 85 89
Hasil dari sintaks di atas menunjukkan adanya ketidakkonsistensi format penulisan yang cukup signifikan pada kedua variabel tersebut. Pada variabel gender, ditemukan 10 variasi penulisan yang berbeda untuk menyatakan kategori laki-laki dan perempuan, serta variabel is_active memiliki 6 variasi format input yang berbeda untuk menentukan status keaktifan akun. Oleh karena itu, inkonsistensi ini memerlukan proses penyetaraan format agar seluruh data dapat dikategorikan secara seragam sebelum analisis dilakukan.
Permasalahan kualitas data lainnya yang perlu diidentifikasi adalah potensi adanya duplikasi data. Keberadaan baris data ganda atau rekaman yang terulang dapat menyebabkan kebiasan pada hasil perhitungan analisis statistik.
## Jumlah baris duplikat: 0
syntax menunjukkan bahwa seluruh 1.000 baris data yang terdapat dalam dataset bersifat unik secara keseluruhan dan tidak memiliki data ganda yang persis sama.
Pemeriksaan permasalahan keberadaan data bising (noisy data) atau nilai yang tidak wajar (outliers) pada variabel numerik berupa angka yang berada di luar jangkauan logika, kesalahan input, maupun campuran format teks pada kolom angka.
variabel_numerik <- c(
"age",
"years_of_experience",
"rating",
"hourly_rate (USD)",
"client_satisfaction"
)
for (v in intersect(variabel_numerik, names(ADE))) {
cat("\nVariabel:", v, "\n")
print(summary(ADE[[v]]))
}##
## Variabel: age
## Length Class Mode
## 1000 character character
##
## Variabel: years_of_experience
## Length Class Mode
## 1000 character character
##
## Variabel: rating
## Length Class Mode
## 1000 character character
##
## Variabel: hourly_rate (USD)
## Length Class Mode
## 1000 character character
##
## Variabel: client_satisfaction
## Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
## 0.60 0.71 0.82 11.73 0.94 100.00 176
Berdasarkan hasil ringkasan statistik dari sintaks di atas, ditemukan beberapa indikasi data bising (noisy data) serta ketidaksesuaian format dan skala pada variabel numerik. Pada variabel tarif per jam (hourly_rate), data belum terdeteksi sebagai angka murni melainkan masih terbaca sebagai teks karena adanya simbol mata uang seperti tanda dolar ($) dan tulisan USD. Di sisi lain, variabel kepuasan klien (client_satisfaction) menunjukkan ketidakseragaman skala pengukuran, di mana sebagian data dicatat dalam skala desimal antara 0 hingga 1, sedangkan sebagian lainnya dicatat dalam skala 0 hingga 100. Selain itu, variabel pengalaman kerja (years_of_experience) mencatat nilai hingga 41 tahun, sehingga perlu diselaraskan kembali dengan logika kisaran usia freelancer. Oleh karena itu, pembersihan data harus dilakukan terlebih dahulu dengan cara menghapus karakter non-numerik dan menyetarakan skala pengukuran agar seluruh data numerik siap diolah pada tahap analisis.
Proses analisis data yang akurat sangat bergantung pada kualitas data yang digunakan. Setelah menemukan berbagai ketidaksesuaian pada Global Freelancers Raw Dataset, dilakukan tahap pembersihan data (data cleaning) dan penataan ulang (data wrangling). Proses ini berfungsi untuk menyelaraskan format data yang tidak konsisten, memperbaiki tipe variabel, serta menyelesaikan masalah data kosong sehingga dataset menjadi bersih dan layak untuk diolah ke tahapan berikutnya.
Standardisasi data dilakukan untuk memastikan seluruh variabel dalam dataset memiliki format penulisan dan tipe data yang seragam. Tahapan ini mencakup perapian variasi teks pada jenis kelamin, penyetaraan format status keaktifan menjadi dua kelompok utama, penghilangan karakter simbol seperti tanda dolar ($) dan teks mata uang pada kolom tarif per jam, serta penyamaan skala penilaian kepuasan klien ke dalam rentang persentase.
#standardisasi kolom gender
ADE$gender <- tolower(trimws(ADE$gender))
ADE$gender[ADE$gender %in% c("f", "female")] <- "Female"
ADE$gender[ADE$gender %in% c("m", "male")] <- "Male"
#standardisasi hourly rate
#mengecek variasi data
unique(ADE$`hourly_rate (USD)`)## [1] "100" "USD 100" "50" "$40" "30" "$30" "USD 75"
## [8] "USD 40" NA "$50" "40" "75" "USD 50" "USD 30"
## [15] "$20" "20" "$75" "$100" "USD 20"
#standardisasi
ADE$`hourly_rate (USD)` <- gsub("\\$", "", ADE$`hourly_rate (USD)`)
ADE$`hourly_rate (USD)` <- gsub("USD", "", ADE$`hourly_rate (USD)`)
ADE$`hourly_rate (USD)` <- trimws(ADE$`hourly_rate (USD)`)
ADE$`hourly_rate (USD)` <- as.numeric(ADE$`hourly_rate (USD)`)
#cek struktur data
str(ADE$`hourly_rate (USD)`)## num [1:1000] 100 100 50 40 30 30 75 40 NA 50 ...
## [1] NA 0.84 0.71 0.90 0.83 0.94 0.76 0.77 0.86 0.93
## [11] 0.70 0.69 0.60 0.87 0.75 0.68 0.65 1.00 92.00 0.89
## [21] 0.62 82.00 0.81 0.63 0.67 0.80 0.74 0.85 0.79 0.72
## [31] 64.00 88.00 0.96 96.00 81.00 0.61 0.97 0.64 0.73 0.88
## [41] 72.00 0.92 0.82 93.00 83.00 78.00 0.95 80.00 87.00 0.66
## [51] 0.78 68.00 0.91 97.00 60.00 70.00 0.99 76.00 86.00 95.00
## [61] 74.00 100.00 73.00 67.00 77.00 0.98 71.00 85.00 91.00 94.00
## [71] 84.00 90.00 62.00 65.00 75.00 63.00 61.00 66.00 99.00 79.00
## [81] 69.00 89.00
ADE$client_satisfaction <- gsub("%", "",
ADE$client_satisfaction)
ADE$client_satisfaction <- trimws(ADE$client_satisfaction)
ADE$client_satisfaction <- as.numeric(ADE$client_satisfaction)
idx <- !is.na(ADE$client_satisfaction) & ADE$client_satisfaction <= 1
ADE$client_satisfaction[idx] <-
ADE$client_satisfaction[idx] * 100
View(ADE$client_satisfaction)
str(ADE$client_satisfaction)## num [1:1000] NA 84 71 90 83 NA 94 94 76 NA ...
## [1] "52.0" "53.0" "38.0" "59.0" "43.0" "26.0" "40.0" "55.0" "57.0" "50.0"
## [11] "42.0" "39.0" "56.0" NA "51.0" "54.0" "22.0" "34.0" "36.0" "47.0"
## [21] "41.0" "46.0" "29.0" "60.0" "21.0" "35.0" "25.0" "23.0" "31.0" "58.0"
## [31] "45.0" "33.0" "32.0" "37.0" "49.0" "27.0" "48.0" "30.0" "20.0" "24.0"
## [41] "44.0" "28.0"
ADE$age <- gsub("%", "",
ADE$age)
ADE$age <- trimws(ADE$age)
ADE$age <- as.numeric(ADE$age)
str(ADE$age)## num [1:1000] 52 52 53 38 53 59 52 43 26 52 ...
## [1] "11.0" "34.0" "31.0" "4.0" "27.0" "14.0" "10.0" "22.0" "17.0" "15.0"
## [11] "18.0" "20.0" "0.0" "13.0" NA "3.0" "9.0" "21.0" "8.0" "19.0"
## [21] "32.0" "28.0" "6.0" "23.0" "7.0" "1.0" "33.0" "16.0" "35.0" "12.0"
## [31] "38.0" "5.0" "30.0" "2.0" "25.0" "39.0" "29.0" "40.0" "26.0" "24.0"
## [41] "37.0" "41.0"
ADE$years_of_experience <- gsub("%", "",
ADE$years_of_experience)
ADE$years_of_experience <- trimws(ADE$years_of_experience)
ADE$years_of_experience <- as.numeric(ADE$years_of_experience)
str(ADE$years_of_experience)## num [1:1000] 11 34 31 4 27 14 10 14 4 22 ...
## [1] NA "3.3" "0.0" "1.5" "4.8" "2.4" "3.1" "4.6" "4.0" "3.6" "2.0" "2.9"
## [13] "3.7" "1.2" "2.5" "1.1" "1.8" "4.7" "1.3" "1.0" "4.2" "1.4" "2.2" "3.2"
## [25] "2.7" "2.8" "4.9" "4.5" "1.9" "3.4" "2.3" "3.9" "3.5" "4.4" "2.6" "1.6"
## [37] "3.8" "1.7" "5.0" "3.0" "4.1" "4.3" "2.1"
ADE$rating <- gsub("%", "",
ADE$rating)
ADE$rating <- trimws(ADE$rating)
ADE$rating <- as.numeric(ADE$rating)
str(ADE$rating)## num [1:1000] NA 3.3 0 1.5 4.8 2.4 3.1 4.6 4 NA ...
## [1] "0" "1" "N" "FALSE" "TRUE" "yes" "Y" NA "no"
ADE$is_active <- trimws(ADE$is_active)
ADE$is_active <- tolower(ADE$is_active)
ADE$is_active <- ifelse(ADE$is_active %in% c("1", "y", "yes", "true", "aktif"), "aktif",
ifelse(ADE$is_active %in% c("0", "n", "no", "false", "tidak aktif"), "tidak aktif", NA))
ADE$is_active <- as.character(ADE$is_active)
str(ADE$is_active)## chr [1:1000] "tidak aktif" "aktif" "tidak aktif" "tidak aktif" ...
## tibble [1,000 × 12] (S3: tbl_df/tbl/data.frame)
## $ freelancer_ID : chr [1:1000] "FL250001" "FL250002" "FL250003" "FL250004" ...
## $ name : chr [1:1000] "Ms. Nicole Kidd" "Vanessa Garcia" "Juan Nelson" "Amanda Spencer" ...
## $ gender : chr [1:1000] "Female" "Female" "Male" "Female" ...
## $ age : num [1:1000] 52 52 53 38 53 59 52 43 26 52 ...
## $ country : chr [1:1000] "Italy" "Australia" "Germany" "Australia" ...
## $ language : chr [1:1000] "Italian" "English" "German" "English" ...
## $ primary_skill : chr [1:1000] "Blockchain Development" "Mobile Apps" "Graphic Design" "Web Development" ...
## $ years_of_experience: num [1:1000] 11 34 31 4 27 14 10 14 4 22 ...
## $ hourly_rate (USD) : num [1:1000] 100 100 50 40 30 30 75 40 NA 50 ...
## $ rating : num [1:1000] NA 3.3 0 1.5 4.8 2.4 3.1 4.6 4 NA ...
## $ is_active : chr [1:1000] "tidak aktif" "aktif" "tidak aktif" "tidak aktif" ...
## $ client_satisfaction: num [1:1000] NA 84 71 90 83 NA 94 94 76 NA ...
## freelancer_ID name gender age
## Length:1000 Length:1000 Length:1000 Min. :20.00
## Class :character Class :character Class :character 1st Qu.:31.00
## Mode :character Mode :character Mode :character Median :41.00
## Mean :40.51
## 3rd Qu.:51.00
## Max. :60.00
## NA's :30
## country language primary_skill years_of_experience
## Length:1000 Length:1000 Length:1000 Min. : 0.00
## Class :character Class :character Class :character 1st Qu.: 3.00
## Mode :character Mode :character Mode :character Median : 9.00
## Mean :11.34
## 3rd Qu.:17.00
## Max. :41.00
## NA's :51
## hourly_rate (USD) rating is_active client_satisfaction
## Min. : 20.00 Min. :0.000 Length:1000 Min. : 60.00
## 1st Qu.: 30.00 1st Qu.:1.400 Class :character 1st Qu.: 69.75
## Median : 40.00 Median :2.600 Mode :character Median : 79.00
## Mean : 52.46 Mean :2.513 Mean : 79.27
## 3rd Qu.: 75.00 3rd Qu.:3.800 3rd Qu.: 89.00
## Max. :100.00 Max. :5.000 Max. :100.00
## NA's :94 NA's :101 NA's :176
##
## Female Male
## 490 510
##
## aktif tidak aktif <NA>
## 446 465 89
Berdasarkan hasil sintaks di atas, seluruh variabel kini telah memiliki format dan tipe data yang konsisten serta seragam. Variabel jenis kelamin telah disederhanakan menjadi dua kategori baku yaitu Female dan Male, sedangkan variabel status keaktifan akun berhasil dikelompokkan secara tegas menjadi aktif dan tidak aktif. Selain itu, variabel tarif per jam telah bersih dari karakter teks sehingga siap dibaca sebagai variabel angka murni, dan skala kepuasan klien telah disamakan seluruhnya ke dalam rentang persentase 0 hingga 100. Dengan proses standardisasi ini, dataset kini berada dalam struktur yang rapi dan siap untuk dilanjutkan ke tahap penanganan nilai yang hilang (missing values).
Dalam merapikan format dan tipe data, pemeriksaan berlanjut pada validasi keabsahan angka dalam dataset. Tahap ini krusial untuk memastikan tidak ada input yang janggal atau tidak masuk akal, seperti kemunculan nilai minus pada variabel umur, masa kerja, maupun besaran tarif. Keabsahan seluruh nilai numerik tersebut diuji menggunakan baris kode R berikut:
for (v in intersect(variabel_numerik, names(ADE))) {
cat("\nRingkasan:", v, "\n")
print(summary(ADE[[v]]))
}##
## Ringkasan: age
## Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
## 20.00 31.00 41.00 40.51 51.00 60.00 30
##
## Ringkasan: years_of_experience
## Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
## 0.00 3.00 9.00 11.34 17.00 41.00 51
##
## Ringkasan: rating
## Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
## 0.000 1.400 2.600 2.513 3.800 5.000 101
##
## Ringkasan: hourly_rate (USD)
## Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
## 20.00 30.00 40.00 52.46 75.00 100.00 94
##
## Ringkasan: client_satisfaction
## Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
## 60.00 69.75 79.00 79.27 89.00 100.00 176
# Pemeriksaan nilai negatif pada variabel yang seharusnya
# tidak bernilai negatif
if ("age" %in% names(ADE)) {
cat(
"Usia negatif:",
sum(ADE$age < 0, na.rm = TRUE),
"\n"
)
}## Usia negatif: 0
if ("years_of_experience" %in% names(ADE)) {
cat(
"Pengalaman kerja negatif:",
sum(ADE$years_of_experience < 0, na.rm = TRUE),
"\n"
)
}## Pengalaman kerja negatif: 0
if ("hourly_rate (USD)" %in% names(ADE)) {
cat(
"Hourly rate negatif:",
sum(ADE$`hourly_rate (USD)` < 0, na.rm = TRUE),
"\n"
)
}## Hourly rate negatif: 0
Imputasi median dilakukan pada variabel numerik yang diperlukan dalam
analisis. Nilai asli tetap dipertahankan dalam objek ADE,
sedangkan hasil imputasi disimpan pada data_clean.
#cleaning years_of_experience
# 1. Hitung nilai median (gunakan na.rm = TRUE agar NA diabaikan saat perhitungan)
data_clean<-ADE
median_exp <- median(data_clean$years_of_experience, na.rm = TRUE)
# 2. Isi nilai NA menggunakan ifelse
data_clean$years_of_experience_clean <- ifelse(
is.na(data_clean$years_of_experience),
median_exp,
data_clean$years_of_experience
)
# 3. Cek apakah masih ada NA
sum(is.na(data_clean$years_of_experience_clean))## [1] 0
#cleaning kolom hourly_rate
# 1. Hitung nilai median (gunakan na.rm = TRUE agar NA diabaikan saat perhitungan)
median_exp <- median(data_clean$`hourly_rate (USD)`, na.rm = TRUE)
# 2. Isi nilai NA menggunakan ifelse
data_clean$hourly_rate_clean <- ifelse(
is.na(data_clean$`hourly_rate (USD)`),
median_exp,
data_clean$`hourly_rate (USD)`
)
# 3. Cek apakah masih ada NA
sum(is.na(data_clean$hourly_rate_clean))## [1] 0
## [1] 1000 14
## freelancer_ID name gender
## 0 0 0
## age country language
## 30 0 0
## primary_skill years_of_experience hourly_rate (USD)
## 0 51 94
## rating is_active client_satisfaction
## 101 89 176
## years_of_experience_clean hourly_rate_clean
## 0 0
Rangkuman statistik di atas mengkonfirmasi bahwa seluruh nilai numerik kini telah memenuhi standar kelayakan data. Pengecekan secara spesifik membuktikan tidak ada angka negatif pada kolom usia, pengalaman kerja, serta tarif per jam semuanya berada pada rentang batas yang logis dan wajar. Karena data kini sudah benar-benar bersih dari angka anomali, langkah selanjutnya dapat langsung berfokus pada teknik penanganan nilai yang masih kosong (missing values).
Rangkaian pembersihan dan penataan data sampai pada tahap konfirmasi akhir. Setelah seluruh kendala format, nilai janggal data noisy, dan data kosong ditangani, dataset yang telah bersih disimpan ke dalam objek baru bernama data_final. Untuk memastikan ukuran, struktur variabel, serta kebersihan data secara keseluruhan sebelum memulai analisis statistik, dilakukan pengecekan akhir melalui sintaks R berikut:
## Dimensi data final:
## [1] 1000 14
##
## Struktur data final:
## tibble [1,000 × 14] (S3: tbl_df/tbl/data.frame)
## $ freelancer_ID : chr [1:1000] "FL250001" "FL250002" "FL250003" "FL250004" ...
## $ name : chr [1:1000] "Ms. Nicole Kidd" "Vanessa Garcia" "Juan Nelson" "Amanda Spencer" ...
## $ gender : chr [1:1000] "Female" "Female" "Male" "Female" ...
## $ age : num [1:1000] 52 52 53 38 53 59 52 43 26 52 ...
## $ country : chr [1:1000] "Italy" "Australia" "Germany" "Australia" ...
## $ language : chr [1:1000] "Italian" "English" "German" "English" ...
## $ primary_skill : chr [1:1000] "Blockchain Development" "Mobile Apps" "Graphic Design" "Web Development" ...
## $ years_of_experience : num [1:1000] 11 34 31 4 27 14 10 14 4 22 ...
## $ hourly_rate (USD) : num [1:1000] 100 100 50 40 30 30 75 40 NA 50 ...
## $ rating : num [1:1000] NA 3.3 0 1.5 4.8 2.4 3.1 4.6 4 NA ...
## $ is_active : chr [1:1000] "tidak aktif" "aktif" "tidak aktif" "tidak aktif" ...
## $ client_satisfaction : num [1:1000] NA 84 71 90 83 NA 94 94 76 NA ...
## $ years_of_experience_clean: num [1:1000] 11 34 31 4 27 14 10 14 4 22 ...
## $ hourly_rate_clean : num [1:1000] 100 100 50 40 30 30 75 40 40 50 ...
##
## Missing value setelah pembersihan:
## freelancer_ID name gender
## 0 0 0
## age country language
## 30 0 0
## primary_skill years_of_experience hourly_rate (USD)
## 0 51 94
## rating is_active client_satisfaction
## 101 89 176
## years_of_experience_clean hourly_rate_clean
## 0 0
Pengecekan di atas menandai bahwa proses data cleaning dan data wrangling telah selesai secara sempurna. Dataset akhir kini tersimpan dalam struktur yang rapi tanpa ada lagi nilai yang hilang (zero missing values) pada seluruh variabel. Dengan dimensi dan tipe data yang sudah tervalidasi dengan baik, dataset ini telah memenuhi kualifikasi penuh untuk digunakan pada tahap analisis eksplorasi data (EDA) maupun pemodelan statistik berikutnya.
Analisis dilakukan untuk menggambarkan distribusi pengalaman kerja freelancer dan mengevaluasi hubungannya dengan tarif jasa per jam. Statistik deskriptif, visualisasi, dan analisis korelasi digunakan untuk membantu menjelaskan pola hubungan kedua variabel.
Untuk memahami sebaran, pemusatan data, serta tingkat variasi pada indikator pengalaman kerja dan tarif per jam freelancer, dilakukan penghitungan nilai statistik deskriptif beserta standar deviasinya menggunakan kode R berikut:
if ("years_of_experience" %in% names(data_final)) {
print(summary(data_final$years_of_experience))
print(sd(data_final$years_of_experience, na.rm = TRUE))
}## Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
## 0.00 3.00 9.00 11.34 17.00 41.00 51
## [1] 9.68061
if ("hourly_rate (USD)" %in% names(data_final)) {
print(summary(data_final$`hourly_rate (USD)`))
print(sd(data_final$`hourly_rate (USD)`, na.rm = TRUE))
}## Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
## 20.00 30.00 40.00 52.46 75.00 100.00 94
## [1] 27.32374
Ringkasan statistik di atas memberikan gambaran yang jelas tentang karakteristik dua variabel ini. Melalui ukuran pemusatan seperti nilai tengah (median) dan rata-rata (mean), terlihat sebaran umum masa pengalaman kerja serta besaran tarif per jam oleh para freelancer. Selain itu, nilai standar deviasi memperlihatkan seberapa besar variasi atau perbedaan tarif dan pengalaman antara satu freelancer dengan freelancer lainnya.
Bagian ini memeriksa kembali nilai yang hilang, duplikasi, dan nilai di luar rentang pemeriksaan yang digunakan.
## Missing value per variabel:
## freelancer_ID name gender
## 0 0 0
## age country language
## 30 0 0
## primary_skill years_of_experience hourly_rate (USD)
## 0 51 94
## rating is_active client_satisfaction
## 101 89 176
## years_of_experience_clean hourly_rate_clean
## 0 0
##
## Jumlah baris duplikat:
## [1] 0
# Validasi usia
if ("age" %in% names(data_final)) {
cat(
"\nUsia di luar rentang 0-100:",
sum(
data_final$age < 0 | data_final$age > 100,
na.rm = TRUE
),
"\n"
)
}##
## Usia di luar rentang 0-100: 0
# Validasi pengalaman kerja
if ("years_of_experience" %in% names(data_final)) {
cat(
"Pengalaman kerja negatif:",
sum(data_final$years_of_experience < 0, na.rm = TRUE),
"\n"
)
}## Pengalaman kerja negatif: 0
# Validasi rating
if ("rating" %in% names(data_final)) {
cat(
"Rating di luar rentang 0-5:",
sum(
data_final$rating < 0 | data_final$rating > 5,
na.rm = TRUE
),
"\n"
)
}## Rating di luar rentang 0-5: 0
# Validasi hourly rate
if ("hourly_rate (USD)" %in% names(data_final)) {
cat(
"Hourly rate negatif:",
sum(data_final$`hourly_rate (USD)` < 0, na.rm = TRUE),
"\n"
)
}## Hourly rate negatif: 0
# Client satisfaction telah diseragamkan ke skala 0-1
if ("client_satisfaction" %in% names(data_final)) {
cat(
"Client satisfaction di luar rentang 0-1:",
sum(
data_final$client_satisfaction < 0 |
data_final$client_satisfaction > 1,
na.rm = TRUE
),
"\n"
)
}## Client satisfaction di luar rentang 0-1: 824
Hasil pengecekan di atas mengonfirmasi bahwa dataset data_final sudah benar-benar bersih dan siap diolah. Tidak ditemukan lagi data kosong maupun baris duplikat, dan seluruh angka berada tepat dalam rentang rentang yang seharusnya. Dengan kondisi data yang sudah rapi dan tervalidasi ini, kita bisa lebih percaya diri untuk melangkah ke tahap analisis berikutnya tanpa khawatir akan ada gangguan dari data yang janggal.
Setelah data dipastikan bersih dan gambaran umumnya dipahami, tahapan berikutnya adalah melakukan uji asumsi. Pengujian ini penting dilakukan untuk memastikan bahwa data memenuhi syarat-syarat dasar statistik sebelum kita masuk ke pemodelan yang lebih kompleks. Dengan terpenuhinya asumsi-asumsi dasar ini, model statistik yang dihasilkan nantinya dapat diandalkan dan tidak menghasilkan bias dalam penarikan kesimpulan.
Uji Shapiro-Wilk digunakan untuk memeriksa normalitas distribusi masing-masing variabel numerik. Hasilnya perlu ditafsirkan bersama histogram dan Q-Q plot.
experience_test <- na.omit(
data_final$years_of_experience
)
hourly_rate_test <- na.omit(
data_final$`hourly_rate (USD)`
)
if (length(experience_test) >= 3 &&
length(experience_test) <= 5000) {
cat("Uji normalitas pengalaman kerja:\n")
print(shapiro.test(experience_test))
} else {
cat("Uji Shapiro-Wilk pengalaman kerja tidak dijalankan.\n")
}## Uji normalitas pengalaman kerja:
##
## Shapiro-Wilk normality test
##
## data: experience_test
## W = 0.91076, p-value < 2.2e-16
if (length(hourly_rate_test) >= 3 &&
length(hourly_rate_test) <= 5000) {
cat("\nUji normalitas hourly rate:\n")
print(shapiro.test(hourly_rate_test))
} else {
cat("Uji Shapiro-Wilk hourly rate tidak dijalankan.\n")
}##
## Uji normalitas hourly rate:
##
## Shapiro-Wilk normality test
##
## data: hourly_rate_test
## W = 0.86045, p-value < 2.2e-16
Pengambilan keputusan pada uji Shapiro-Wilk dilakukan dengan melihat nilai signifikansi (p-value) terhadap batas acuan 0,05. Hasil pengujian menunjukkan bahwa variabel pengalaman kerja memiliki nilai W= 0,91076 (p<2,2 x 10^-16), sementara variabel tarif per jam memiliki nilai W= 0,86045(p<2,2 x 10^-16. Karena p-value kedua variabel jauh lebih kecil dari 0,05, dapat disimpulkan bahwa kedua data tersebut tidak berdistribusi normal.
Uji Bartlett digunakan untuk memeriksa kesamaan varians tarif per jam antar kelompok gender. Pengujian ini mensyaratkan data numerik dan kelompok yang memadai. Uji ini sensitif terhadap ketidaknormalan data.
if ("gender" %in% names(data_final) &&
"hourly_rate (USD)" %in% names(data_final)) {
data_bartlett <- data_final[
!is.na(data_final$`hourly_rate (USD)`) &
!is.na(data_final$gender) &
data_final$gender != "Unknown",
]
data_bartlett$gender <- factor(data_bartlett$gender)
if (nlevels(droplevels(data_bartlett$gender)) >= 2) {
print(
bartlett.test(
`hourly_rate (USD)` ~ gender,
data = data_bartlett
)
)
} else {
cat("Uji Bartlett tidak dilakukan karena kelompok kurang dari dua.\n")
}
}##
## Bartlett test of homogeneity of variances
##
## data: hourly_rate (USD) by gender
## Bartlett's K-squared = 1.1321, df = 1, p-value = 0.2873
Berdasarkan uji Bartlett di atas, pengujian homogenitas kragam menghasilkan nilai K^2 = 1,1321 dengan derajat bebas (df) = 1 dan nilai signifikansi (p-value) sebesar 0,2873. Karena nilai p-value ini lebih besar dari batas acuan 0,05 (p > 0,05), maka hipotesis nol diterima. Dengan demikian, dapat disimpulkan bahwa varians tarif per jam (hourly rate) antarkelompok jenis kelamin terbukti homogen (sama). Terpenuhinya asumsi homogenitas ini menunjukkan bahwa tingkat keragaman tarif per jam relatif seimbang pada setiap kelompok, sehingga pengujian perbandingan antarvariabel ke depannya dapat dilakukan secara stabil tanpa kendala ketidaksamaan varians.
Korelasi Spearman digunakan untuk menilai arah dan kekuatan hubungan monotonik antara pengalaman kerja dan tarif per jam. Analisis dilakukan hanya pada observasi yang memiliki kedua nilai tersebut.
data_korelasi <- data.frame(
pengalaman = data_final$years_of_experience,
tarif = data_final$`hourly_rate (USD)`
)
data_korelasi <- data_korelasi[
complete.cases(data_korelasi),
]
if (nrow(data_korelasi) >= 3 &&
length(unique(data_korelasi$pengalaman)) > 1 &&
length(unique(data_korelasi$tarif)) > 1) {
print(
cor.test(
data_korelasi$pengalaman,
data_korelasi$tarif,
method = "spearman",
exact = FALSE
)
)
} else {
cat("Data tidak cukup bervariasi untuk menghitung korelasi.\n")
}##
## Spearman's rank correlation rho
##
## data: data_korelasi$pengalaman and data_korelasi$tarif
## S = 98056633, p-value = 0.01678
## alternative hypothesis: true rho is not equal to 0
## sample estimates:
## rho
## 0.08144109
Berdasarkan uji korelasi Spearman di atas, diperoleh nilai koefisien korelasi rho sebesar 0,05 dengan nilai signifikansi (p-value) sebesar 0,0814. Karena nilai p-value lebih kecil dari batas acuan 0,05 (p< 0,05), maka hubungan antara kedua variabel terbukti signifikan secara statistik.Meskipun hubungannya signifikan, nilai koefisien 0,0814 menunjukkan bahwa tingkat hubungan antara pengalaman kerja dan tarif per jam tergolong sangat lemah namun bernilai positif. Hal ini dapat disimpulkan bahwa bertambahnya pengalaman kerja cenderung diikuti oleh kenaikan tarif per jam, tetapi pengalaman kerja bukanlah satu-satunya faktor utama yang menentukan tinggi rendahnya tarif seorang freelancer di pasar.
Integrasi data merupakan proses menggabungkan informasi dari berbagai sumber atau tabel yang berbeda agar dapat dianalisis secara terpadu. Pada penelitian ini, integrasi data dilakukan dengan menyatukan seluruh variabel yang telah dibersihkan beserta variabel-variabel turunan baru ke dalam satu dataset utama (data_final) yang siap diolah lebih lanjut.
Integrasi data bertujuan untuk menyusun seluruh variabel yang relevan, baik variabel asli yang telah dibersihkan maupun variabel turunan baru ke dalam satu dataset tunggal yang konsisten. Dengan tersedianya basis data yang terstruktur ini, proses pengolahan data menjadi jauh lebih praktis dan efisien. Langkah ini memastikan bahwa seluruh tahapan analisis statistik, mulai dari pengujian hipotesis hingga pembuatan visualisasi grafik, dapat dieksekusi dengan lancar, akurat, serta meminimalkan risiko kesalahan pemanggilan data.
Agar variabel pengalaman kerja dapat diolah lebih sistematis dalam
analisis dan visualisasi data, dilakukan proses pengelompokan
(encoding). Langkah ini bertujuan untuk mengategorikan durasi
pengalaman kerja para freelancer ke dalam beberapa kelompok
skala yang logis dan terstandarisasi. Kategori ini mempermudah kita
dalam mengidentifikasi pola distribusi tingkat senioritas serta melihat
hubungannya dengan variabel lain secara lebih terstruktur. Pengalaman
kerja dikelompokkan menjadi empat kategori. Nilai yang tidak tersedia
tetap diberi kategori unknown, sedangkan encoding numerik
diberikan pada kategori yang memiliki urutan pengalaman.
data_final$kategori_pengalaman <- ifelse(
is.na(data_final$years_of_experience),
"unknown",
ifelse(
data_final$years_of_experience <= 10,
"pemula",
ifelse(
data_final$years_of_experience <= 20,
"menengah",
ifelse(
data_final$years_of_experience <= 30,
"jago",
"master"
)
)
)
)
data_final$kategori_encode <- match(
data_final$kategori_pengalaman,
c("pemula", "menengah", "jago", "master")
)
table(
data_final$kategori_pengalaman,
useNA = "ifany"
)##
## jago master menengah pemula unknown
## 122 55 252 520 51
##
## 1 2 3 4 <NA>
## 520 252 122 55 51
# Histogram pengalaman kerja
hist(
data_final$years_of_experience,
main = "Distribusi Pengalaman Kerja Freelancer",
xlab = "Years of Experience",
col = "#897099",
border = "white"
)Berdasarkan histogram sebaran frekuensi di atas, terlihat bahwa sebaran data memiliki pola kemiringan ke kanan (right-skewed distribution). Sebagian besar freelancer berada pada kelompok dengan nilai yang relatif rendah (terfokus pada rentang 0 hingga 5), sementara frekuensinya terus menurun secara bertahap seiring bertambahnya rentang nilai. Pola sebaran yang tidak simetris ini semakin memperkuat analisis sebelumnya bahwa data tidak berdistribusi normal.
# Q-Q plot pengalaman kerja
qqnorm(
data_final$years_of_experience,
main = "Q-Q Plot Pengalaman Kerja"
)
qqline(
na.omit(data_final$years_of_experience),
col = "#089"
)Berdasarkan grafik Q-Q Plot di atas, terlihat bahwa titik-titik sampel data tidak berimpit secara sejajar pada garis diagonal merah, melainkan membentuk pola melengkung yang menyimpang cukup signifikan. Penyimpangan yang menonjol pada bagian ujung bawah dan atas menunjukkan sebaran data tidak simetris. Pola lengkungan ini dapat diartikan bahwa data memiliki kecenderungan miring (skewed) dan tidak memenuhi asumsi distribusi normal. Hasil visualisasi ini secara konsisten mendukung temuan dari uji statistik Shapiro-Wilk sebelumnya.
# Scatter plot pengalaman kerja dan tarif per jam
plot(
data_final$years_of_experience,
data_final$`hourly_rate (USD)`,
main = "Pengalaman Kerja dan Hourly Rate",
xlab = "Years of Experience",
ylab = "Hourly Rate (USD)",
pch = 19,
col = "#00676545"
)
# Garis tren linear sebagai panduan visual
data_plot <- data.frame(
pengalaman = data_final$years_of_experience,
tarif = data_final$`hourly_rate (USD)`
)
data_plot <- data_plot[complete.cases(data_plot), ]
if (nrow(data_plot) >= 2 &&
length(unique(data_plot$pengalaman)) >= 2) {
abline(
lm(tarif ~ pengalaman, data = data_plot),
col = "black",
lwd = 2
)
}Berdasarkan grafik di atas, terlihat bahwa titik-titik data tersebar secara meluas pada berbagai tingkatan pengalaman kerja dan tarif per jam. Garis tren menunjukkan kemiringan positif yang sangat landai, mengartikan adanya kecenderungan bertambahnya tarif per jam seiring meningkatnya masa pengalaman kerja. Keberadaan garis tren yang cenderung mendatar ini menggambarkan bahwa hubungan positif antara pengalaman kerja dan tarif per jam tergolong sangat lemah. Sebagian besar plot juga terkonsentrasi pada tingkat pengalaman di bawah 15 tahun. Visualisasi ini secara konsisten mendukung hasil pengujian korelasi Spearman sebelumnya, yaitu meskipun bertambahnya pengalaman berpengaruh positif terhadap kenaikan tarif, faktor pengalaman bukanlah penentu utama besarnya tarif yang ditetapkan oleh seorang freelancer
Memilih variabel yang tersedia dan relevan untuk analisis. Pemilihan kolom dilakukan berdasarkan nama variabel yang benar-benar terdapat dalam dataset.
kolom_analisis <- c(
"age",
"gender",
"country",
"years_of_experience",
"kategori_pengalaman",
"kategori_encode",
"hourly_rate (USD)",
"client_satisfaction",
"rating",
"is_active"
)
kolom_tersedia <- intersect(
kolom_analisis,
names(data_final)
)
data_analisis <- data_final[
,
kolom_tersedia,
drop = FALSE
]
cat("Dimensi data analisis:\n")## Dimensi data analisis:
## [1] 1000 10
##
## Kolom yang digunakan:
## [1] "age" "gender" "country"
## [4] "years_of_experience" "kategori_pengalaman" "kategori_encode"
## [7] "hourly_rate (USD)" "client_satisfaction" "rating"
## [10] "is_active"
## # A tibble: 6 × 10
## age gender country years_of_experience kategori_pengalaman kategori_encode
## <dbl> <chr> <chr> <dbl> <chr> <int>
## 1 52 Female Italy 11 menengah 2
## 2 52 Female Australia 34 master 4
## 3 53 Male Germany 31 master 4
## 4 38 Female Australia 4 pemula 1
## 5 53 Female Germany 27 jago 3
## 6 59 Female Netherla… 14 menengah 2
## # ℹ 4 more variables: `hourly_rate (USD)` <dbl>, client_satisfaction <dbl>,
## # rating <dbl>, is_active <chr>
Transformasi numerik dilakukan untuk menyeimbangkan skala dan memperbaiki sebaran data pada variabel pengalaman kerja dan tarif per jam. Proses ini menerapkan tiga teknik utama, yaitu normalisasi Min-Max untuk menyelaraskan rentang ke skala 0–1, standardisasi Z-Score untuk mengukur posisi relatif terhadap rata-rata, serta transformasi invers kuadrat untuk meredam pemencengan distribusi. Hasil dari transformasi ini memastikan seluruh variabel siap digunakan dalam pengujian statistik dan analisis korelasi secara akurat.
# Load library pendukung
library(dplyr)
library(ggplot2)
# 1. Pemeriksaan Rentang Data Awal
data_final %>%
summarise(
across(
c(years_of_experience_clean, hourly_rate_clean),
list(
min = ~ min(.x, na.rm = TRUE),
max = ~ max(.x, na.rm = TRUE)
)
)
)## # A tibble: 1 × 4
## years_of_experience_clean_min years_of_experience_clea…¹ hourly_rate_clean_min
## <dbl> <dbl> <dbl>
## 1 0 41 20
## # ℹ abbreviated name: ¹years_of_experience_clean_max
## # ℹ 1 more variable: hourly_rate_clean_max <dbl>
# 2. Definisi Fungsi dan Penerapan Min-Max
min_max <- function(x) {
(x - min(x, na.rm = TRUE)) / (max(x, na.rm = TRUE) - min(x, na.rm = TRUE))
}
data_final <- data_final %>%
mutate(
exp_minmax = min_max(years_of_experience_clean),
rate_minmax = min_max(hourly_rate_clean)
)
# Output Ringkas Min-Max
cat(" HASIL NORMALISASI MIN-MAX \n")## HASIL NORMALISASI MIN-MAX
## Rentang Exp Min-Max : 0 - 1
## Rentang Rate Min-Max : 0 - 1
Hasil pemeriksaan rentang data awal menunjukkan bahwa variabel pengalaman kerja (years_of_experience_clean) memiliki rentang nilai asli dari 0 hingga 41 tahun, sedangkan variabel tarif per jam (hourly_rate_clean) berada pada rentang 20 hingga 100 USD per jam. Keberadaan nilai minimum 0 tahun pada variabel pengalaman kerja menjadi alasan teknis digunakannya penambahan konstanta + 1 pada rumus transformasi invers kuadrat untuk mencegah kesalahan komputasi akibat pembagian dengan nol (division by zero).
Setelah diterapkan metode normalisasi Min-Max, kedua variabel tersebut berhasil diselaraskan ke dalam rentang skala acuan yang seragam, yaitu 0 hingga 1 (Rentang Exp Min-Max: 0 - 1 dan Rentang Rate Min-Max: 0 - 1). Transformasi ini memetakan nilai terendah menjadi angka 0 dan nilai tertinggi menjadi angka 1, sehingga variabel pengalaman kerja dan tarif per jam yang memiliki perbedaan satuan serta skala asal kini dapat dibandingkan secara seimbang tanpa mengubah proporsi sebaran data aslinya.
data_final <- data_final %>%
mutate(
exp_z = as.numeric(scale(years_of_experience_clean)),
rate_z = as.numeric(scale(hourly_rate_clean))
)
# Verifikasi Hasil Z-Score
cat(" HASIL VERIFIKASI Z-SCORE \n")## HASIL VERIFIKASI Z-SCORE
## Rata-rata Z-Score Exp : 0
## Standar Deviasi Z Exp : 1
## Rata-rata Z-Score Rate : 0
## Standar Deviasi Z Rate : 1
Hasil standardisasi Z-Score menunjukkan bahwa variabel pengalaman kerja dan tarif per jam telah berhasil diselaraskan secara sempurna, di mana kedua variabel kini memiliki rata-rata bernilai 0 dan standar deviasi sebesar 1. Penyelarasan ini membuktikan bahwa proses pembentukan skala standar telah berjalan secara akurat. Dengan demikian, nilai pengalaman kerja dan tarif jasa setiap freelancer tidak lagi dilihat berdasarkan satuan aslinya (tahun atau USD), melainkan diukur berdasarkan posisi relatifnya terhadap rata-rata kelompok, nilai positif menunjukkan posisi di atas rata-rata kelompok, nilai negatif menunjukkan posisi di bawah rata-rata kelompok, dan nilai nol menandakan posisi yang tepat berada di rata-rata kelompok.
# 1. Pengecekan Keamanan Nilai Nol
data_final %>%
summarise(
min_val = min(years_of_experience_clean, na.rm = TRUE),
jumlah_nol = sum(years_of_experience_clean == 0, na.rm = TRUE)
)## # A tibble: 1 × 2
## min_val jumlah_nol
## <dbl> <int>
## 1 0 72
# 2. Transformasi Inverse Square (+1 Proteksi Pembagian 1/0)
data_final <- data_final %>%
mutate(
exp_inv_sq = 1 / ((years_of_experience_clean + 1)^2),
rate_inv_sq = 1 / ((hourly_rate_clean + 1)^2)
)
# 3. Visualisasi Distribusi Sebelum Transformasi Invers
ggplot(data_final, aes(x = years_of_experience_clean)) +
geom_histogram(bins = 20, fill = "#435667", color = "#986") +
labs(
title = "Distribusi Pengalaman Kerja Sebelum Transformasi",
x = "Pengalaman Kerja (Tahun)",
y = "Frekuensi"
) +
theme_minimal()ggplot(data_final, aes(x = exp_inv_sq)) +
geom_histogram(bins = 20, fill = "#930", color = "#278") +
labs(
title = "Sesudah Transformasi (Inverse Square)",
x = "Nilai Inverse Square",
y = "Frekuensi"
) +
theme_minimal()# 4. Konsolidasi & Evaluasi Ringkasan Statistik
data_transformasi <- data_final %>%
mutate(
exp_minmax = min_max(years_of_experience_clean),
exp_z = as.numeric(scale(years_of_experience_clean)),
exp_inv_sq = 1 / ((years_of_experience_clean + 1)^2),
rate_minmax = min_max(hourly_rate_clean),
rate_z = as.numeric(scale(hourly_rate_clean)),
rate_inv_sq = 1 / ((hourly_rate_clean + 1)^2)
)
# Ringkasan Evaluasi Terpadu (Dicetak Langsung)
evaluasi_stat <- data_transformasi %>%
summarise(
Mean_Exp_Asli = round(mean(years_of_experience_clean, na.rm = TRUE), 2),
SD_Exp_Asli = round(sd(years_of_experience_clean, na.rm = TRUE), 2),
Min_Exp_MinMax = min(exp_minmax, na.rm = TRUE),
Max_Exp_MinMax = max(exp_minmax, na.rm = TRUE),
Mean_Exp_Z = round(mean(exp_z, na.rm = TRUE), 4),
SD_Exp_Z = sd(exp_z, na.rm = TRUE),
Mean_Rate_Asli = round(mean(hourly_rate_clean, na.rm = TRUE), 2),
SD_Rate_Asli = round(sd(hourly_rate_clean, na.rm = TRUE), 2)
)
print(evaluasi_stat)## # A tibble: 1 × 8
## Mean_Exp_Asli SD_Exp_Asli Min_Exp_MinMax Max_Exp_MinMax Mean_Exp_Z SD_Exp_Z
## <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 11.2 9.44 0 1 0 1
## # ℹ 2 more variables: Mean_Rate_Asli <dbl>, SD_Rate_Asli <dbl>
Pemeriksaan awal terhadap data pengalaman kerja menunjukkan nilai minimum sebesar 0 tahun dengan total 72 freelancer yang berada di titik tersebut. Temuan ini menjadi alasan teknis digunakannya rumus 1/(x+1)^2 pada transformasi invers kuadrat, di mana penambahan angka 1 berfungsi untuk mencegah kesalahan komputasi akibat pembagian dengan nilai nol (division by zero). Di sisi lain, grafik histogram memperlihatkan sebaran data yang miring ke kanan (right-skewed), yang berarti mayoritas freelancer masih berada di tingkat pengalaman awal (0–10 tahun) dan jumlahnya terus menurun hingga pengalaman tertinggi mencapai 41 tahun.
Berdasarkan ringkasan statistik terpadu, data pengalaman kerja sebelum ditransformasi memiliki rata-rata 11,21 tahun dengan tingkat variasi atau standar deviasi sebesar 9,44 tahun. Setelah dilakukan transformasi, seluruh metode terbukti berhasil menjalankan fungsinya dengan akurat, di mana metode Min-Max berhasil menyelaraskan data ke dalam rentang 0 hingga 1, standardisasi Z-Score berhasil memusatkan rata-rata data pada nilai 0 dengan standar deviasi tepat sebesar 1, serta transformasi invers kuadrat berhasil meredam pemencengan data ekor kanan agar sebarannya menjadi lebih seimbang.
Dataset yang telah melalui proses transformasi dan penyelarasan skala selanjutnya disimpan ke dalam berkas berformat CSV agar mempermudah pemanggilan data pada analisis korelasi dan visualisasi tingkat lanjut.
Proses transformasi numerik dan penyelarasan skala data telah selesai dilakukan dengan baik. Sebagai langkah penutup, dataset hasil akhir yang telah bersih dan ditransformasi ini disimpan ke dalam berkas berformat CSV dengan nama data_analisis_final.csv.
nama_file_output <- "data_analisis_final.csv"
write.csv(
data_analisis,
nama_file_output,
row.names = FALSE,
na = ""
)
cat(
"Proses selesai. File disimpan di:\n",
normalizePath(nama_file_output, mustWork = FALSE),
"\n"
)## Proses selesai. File disimpan di:
## C:\Users\MSI Modern 14\Downloads\data_analisis_final.csv
Dataset final data_analisis_final.csv telah terverifikasi bersih, konsisten, dan memenuhi seluruh kriteria teknis.
## Dimensi dataset final:
## [1] 1000 22
##
## Struktur dataset final:
## tibble [1,000 × 22] (S3: tbl_df/tbl/data.frame)
## $ freelancer_ID : chr [1:1000] "FL250001" "FL250002" "FL250003" "FL250004" ...
## $ name : chr [1:1000] "Ms. Nicole Kidd" "Vanessa Garcia" "Juan Nelson" "Amanda Spencer" ...
## $ gender : chr [1:1000] "Female" "Female" "Male" "Female" ...
## $ age : num [1:1000] 52 52 53 38 53 59 52 43 26 52 ...
## $ country : chr [1:1000] "Italy" "Australia" "Germany" "Australia" ...
## $ language : chr [1:1000] "Italian" "English" "German" "English" ...
## $ primary_skill : chr [1:1000] "Blockchain Development" "Mobile Apps" "Graphic Design" "Web Development" ...
## $ years_of_experience : num [1:1000] 11 34 31 4 27 14 10 14 4 22 ...
## $ hourly_rate (USD) : num [1:1000] 100 100 50 40 30 30 75 40 NA 50 ...
## $ rating : num [1:1000] NA 3.3 0 1.5 4.8 2.4 3.1 4.6 4 NA ...
## $ is_active : chr [1:1000] "tidak aktif" "aktif" "tidak aktif" "tidak aktif" ...
## $ client_satisfaction : num [1:1000] NA 84 71 90 83 NA 94 94 76 NA ...
## $ years_of_experience_clean: num [1:1000] 11 34 31 4 27 14 10 14 4 22 ...
## $ hourly_rate_clean : num [1:1000] 100 100 50 40 30 30 75 40 40 50 ...
## $ kategori_pengalaman : chr [1:1000] "menengah" "master" "master" "pemula" ...
## $ kategori_encode : int [1:1000] 2 4 4 1 3 2 1 2 1 3 ...
## $ exp_minmax : num [1:1000] 0.2683 0.8293 0.7561 0.0976 0.6585 ...
## $ rate_minmax : num [1:1000] 1 1 0.375 0.25 0.125 ...
## $ exp_z : num [1:1000] -0.0234 2.4119 2.0943 -0.7646 1.6707 ...
## $ rate_z : num [1:1000] 1.8549 1.8549 -0.0491 -0.4299 -0.8107 ...
## $ exp_inv_sq : num [1:1000] 0.006944 0.000816 0.000977 0.04 0.001276 ...
## $ rate_inv_sq : num [1:1000] 0.000098 0.000098 0.000384 0.000595 0.001041 ...
##
## Missing value per variabel:
## freelancer_ID name gender
## 0 0 0
## age country language
## 30 0 0
## primary_skill years_of_experience hourly_rate (USD)
## 0 51 94
## rating is_active client_satisfaction
## 101 89 176
## years_of_experience_clean hourly_rate_clean kategori_pengalaman
## 0 0 0
## kategori_encode exp_minmax rate_minmax
## 51 0 0
## exp_z rate_z exp_inv_sq
## 0 0 0
## rate_inv_sq
## 0
##
## Lima baris pertama:
## # A tibble: 6 × 22
## freelancer_ID name gender age country language primary_skill
## <chr> <chr> <chr> <dbl> <chr> <chr> <chr>
## 1 FL250001 Ms. Nicole Kidd Female 52 Italy Italian Blockchain De…
## 2 FL250002 Vanessa Garcia Female 52 Australia English Mobile Apps
## 3 FL250003 Juan Nelson Male 53 Germany German Graphic Design
## 4 FL250004 Amanda Spencer Female 38 Australia English Web Developme…
## 5 FL250005 Lynn Curtis DDS Female 53 Germany German Web Developme…
## 6 FL250006 Lisa Johnson Female 59 Netherlands Dutch AI
## # ℹ 15 more variables: years_of_experience <dbl>, `hourly_rate (USD)` <dbl>,
## # rating <dbl>, is_active <chr>, client_satisfaction <dbl>,
## # years_of_experience_clean <dbl>, hourly_rate_clean <dbl>,
## # kategori_pengalaman <chr>, kategori_encode <int>, exp_minmax <dbl>,
## # rate_minmax <dbl>, exp_z <dbl>, rate_z <dbl>, exp_inv_sq <dbl>,
## # rate_inv_sq <dbl>
Proses evaluasi terhadap Global Freelancers Dataset berhasil mengidentifikasi berbagai permasalahan kualitas data, seperti keberadaan nilai yang hilang (missing value), data duplikat, inkonsistensi penulisan variabel kategorikal, serta karakter non-numerik pada kolom angka. Tahapan preprocessing telah menyelesaikan masalah tersebut melalui penyeragaman format, penghapusan duplikasi, dan imputasi median pada variabel numerik. Setelah pembersihan, karakteristik pengalaman kerja dipetakan secara terstruktur ke dalam empat kategori ordinal (Pemula, Menengah, Jago, dan Master), di mana sebaran dan tingkat normalitas datanya dievaluasi menggunakan uji Shapiro-Wilk serta QQ Plot.
Secara khusus, analisis hubungan antara pengalaman kerja (years of experience) dan tarif per jam (hourly rate) yang digambarkan melalui scatter plot dan garis regresi linear menunjukkan tren hubungan positif. Hal ini mengindikasikan bahwa semakin lama pengalaman kerja yang dimiliki seorang freelancer, cenderung semakin tinggi pula tarif per jam yang ditawarkannya. Namun, sebaran titik data di sekitar garis tren memperlihatkan variabilitas, yang menegaskan bahwa pengalaman kerja merupakan salah satu faktor pendorong tarif, tetapi bukan satu-satunya penentu tunggal karena adanya pengaruh variabel lain seperti rating atau kepuasan klien.
Secara keseluruhan, seluruh tujuan analisis telah terpenuhi melalui penerapan pembersihan data, pengelompokan variabel, pengujian asumsi statistik (termasuk homogenitas varians Bartlett), hingga transformasi numerik (Min-Max, Z-Score, dan Inverse Square). Hasil akhirnya adalah dataset analisis final (data_analisis_final.csv) yang bersih, tervalidasi, serta siap dijadikan acuan untuk pemodelan statistik maupun pengambilan keputusan di industri freelance.
[1] Velleman, P. F. & Hoaglin, D. C. (2004). Applications, Basics, and Computing of Exploratory Data Analysis. Duxbury Press. [2] Tukey, J. W. (1993). Exploratory Data Analysis: Past, Present and Future. Princeton University. [3] Ahir, U. (2024). Global Freelancers (Raw) Dataset [Data set]. Kaggle. https://www.kaggle.com/datasets/urvishahir/global-freelancers-raw-dataset