DMBG #5

Import Data

library(readr)
library(janitor)
## 
## Attaching package: 'janitor'
## The following objects are masked from 'package:stats':
## 
##     chisq.test, fisher.test
dataset<-read_csv("C:/Users/User/Downloads/data_latihan_preprocessing.csv")
## Rows: 1010 Columns: 13
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (8): nama_kepala_rumah_tangga, status_perkawinan, tingkat_pendidikan, je...
## dbl (5): id, pendapatan_tahunan, pengeluaran_bulanan, jumlah_anggota_keluarg...
## 
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.

Cek Struktur Data

str(dataset)
## spc_tbl_ [1,010 × 13] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
##  $ id                      : num [1:1010] 1 2 3 4 5 6 7 8 9 10 ...
##  $ nama_kepala_rumah_tangga: chr [1:1010] "Kepala Rumah Tangga 1" "Kepala Rumah Tangga 2" "Kepala Rumah Tangga 3" "Kepala Rumah Tangga 4" ...
##  $ status_perkawinan       : chr [1:1010] "Cerai" "Cerai" "Cerai" "Belum Menikah" ...
##  $ tingkat_pendidikan      : chr [1:1010] "Sarjana" "SMP" "SMA" "Magister" ...
##  $ jenis_pekerjaan         : chr [1:1010] "Swasta" "PNS" "Nelayan" "Petani" ...
##  $ kepemilikan_rumah       : chr [1:1010] "Sewa" "Sewa" "Milik Sendiri" "Milik Sendiri" ...
##  $ akses_internet          : chr [1:1010] "Tidak" "Ya" "Ya" "Tidak" ...
##  $ jenis_kelamin           : chr [1:1010] "Perempuan" "Perempuan" "Laki-laki" "Laki-laki" ...
##  $ wilayah                 : chr [1:1010] "Pedesaan" "Perkotaan" "Pedesaan" "Pedesaan" ...
##  $ pendapatan_tahunan      : num [1:1010] 5.25e+07 1.31e+08 8.34e+07 5.58e+07 3.09e+07 ...
##  $ pengeluaran_bulanan     : num [1:1010] 4230566 5374996 5477829 5062174 NA ...
##  $ jumlah_anggota_keluarga : num [1:1010] 2 4 6 6 5 6 6 6 5 2 ...
##  $ umur_kepala_rumah_tangga: num [1:1010] 64 80 77 40 59 24 71 78 61 77 ...
##  - attr(*, "spec")=
##   .. cols(
##   ..   id = col_double(),
##   ..   nama_kepala_rumah_tangga = col_character(),
##   ..   status_perkawinan = col_character(),
##   ..   tingkat_pendidikan = col_character(),
##   ..   jenis_pekerjaan = col_character(),
##   ..   kepemilikan_rumah = col_character(),
##   ..   akses_internet = col_character(),
##   ..   jenis_kelamin = col_character(),
##   ..   wilayah = col_character(),
##   ..   pendapatan_tahunan = col_double(),
##   ..   pengeluaran_bulanan = col_double(),
##   ..   jumlah_anggota_keluarga = col_double(),
##   ..   umur_kepala_rumah_tangga = col_double()
##   .. )
##  - attr(*, "problems")=<externalptr>

Terdapat kesalahan tipe data unutk id. Dimana id yang seharusnya dalam bentuk string/character teridentifikasi sebagai numeric

dataset$id<-as.character(dataset$id)

Cek Duplikasi data

get_dupes(dataset)
## No variable names specified - using all columns.
## # A tibble: 14 × 14
##    id    nama_kepala_rumah_tangga status_perkawinan tingkat_pendidikan
##    <chr> <chr>                    <chr>             <chr>             
##  1 185   Kepala Rumah Tangga 185  Cerai             Sarjana           
##  2 185   Kepala Rumah Tangga 185  Cerai             Sarjana           
##  3 205   Kepala Rumah Tangga 205  Janda/Duda        SMP               
##  4 205   Kepala Rumah Tangga 205  Janda/Duda        SMP               
##  5 522   Kepala Rumah Tangga 522  Janda/Duda        Sarjana           
##  6 522   Kepala Rumah Tangga 522  Janda/Duda        Sarjana           
##  7 54    Kepala Rumah Tangga 54   Menikah           Diploma           
##  8 54    Kepala Rumah Tangga 54   Menikah           Diploma           
##  9 627   Kepala Rumah Tangga 627  Menikah           Doktor            
## 10 627   Kepala Rumah Tangga 627  Menikah           Doktor            
## 11 765   Kepala Rumah Tangga 765  Belum Menikah     SMP               
## 12 765   Kepala Rumah Tangga 765  Belum Menikah     SMP               
## 13 779   Kepala Rumah Tangga 779  Janda/Duda        SD                
## 14 779   Kepala Rumah Tangga 779  Janda/Duda        SD                
## # ℹ 10 more variables: jenis_pekerjaan <chr>, kepemilikan_rumah <chr>,
## #   akses_internet <chr>, jenis_kelamin <chr>, wilayah <chr>,
## #   pendapatan_tahunan <dbl>, pengeluaran_bulanan <dbl>,
## #   jumlah_anggota_keluarga <dbl>, umur_kepala_rumah_tangga <dbl>,
## #   dupe_count <int>

Terdapat tujuh amatan yang terduplikasi sehingga perlu dilakukan penanganan dengan menghilangkan duplikasi

library(dplyr)
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
dataset<- distinct(dataset)

Selain itu dengan asumsi variabel id adalah primary keys akan diliat duplikasi dengan indikator variabel id

get_dupes(dataset,id)
## # A tibble: 6 × 14
##   id    dupe_count nama_kepala_rumah_tangga status_perkawinan tingkat_pendidikan
##   <chr>      <int> <chr>                    <chr>             <chr>             
## 1 309            2 Kepala Rumah Tangga 309  10                Doktor            
## 2 309            2 Kepala Rumah Tangga 309  10                Doktor            
## 3 413            2 Kepala Rumah Tangga 413  Belum Menikah     SMP               
## 4 413            2 Kepala Rumah Tangga 413  Belum Menikah     SMP               
## 5 875            2 Kepala Rumah Tangga 875  Belum Menikah     Doktor            
## 6 875            2 Kepala Rumah Tangga 875  Belum Menikah     <NA>              
## # ℹ 9 more variables: jenis_pekerjaan <chr>, kepemilikan_rumah <chr>,
## #   akses_internet <chr>, jenis_kelamin <chr>, wilayah <chr>,
## #   pendapatan_tahunan <dbl>, pengeluaran_bulanan <dbl>,
## #   jumlah_anggota_keluarga <dbl>, umur_kepala_rumah_tangga <dbl>

Terlihat adanya duplikasi yang tidak terdeteksinya jika menggunakan semua variabel dalam penggkategoriannya. Sehingga baris yang duplikat akan dihapus dan dipertahankan yang memiliki infomasi paling lengkap.

library(janitor)
library(dplyr)

dupes <- get_dupes(dataset, id)
dupe_ids <- unique(dupes$id)
rows_to_remove <- dataset %>%
  filter(id %in% dupe_ids) %>%
  filter(if_any(everything(), is.na))
dataset <- anti_join(dataset, rows_to_remove)
## Joining with `by = join_by(id, nama_kepala_rumah_tangga, status_perkawinan,
## tingkat_pendidikan, jenis_pekerjaan, kepemilikan_rumah, akses_internet,
## jenis_kelamin, wilayah, pendapatan_tahunan, pengeluaran_bulanan,
## jumlah_anggota_keluarga, umur_kepala_rumah_tangga)`

Cek Konsistensi Data

char_vars <- sapply(dataset, is.character)
char_vars[c("nama_kepala_rumah_tangga", "id")] <- FALSE
for (var in names(dataset)[char_vars]) {
  cat("Levels of", var, ":\n")
  print(levels(as.factor(dataset[[var]])))
  cat("\n")
}
## Levels of status_perkawinan :
##  [1] "1"             "10"            "2"             "3"            
##  [5] "4"             "5"             "6"             "7"            
##  [9] "8"             "9"             "Belum Menikah" "Cerai"        
## [13] "Janda/Duda"    "Menikah"      
## 
## Levels of tingkat_pendidikan :
##  [1] "1"        "10"       "2"        "3"        "4"        "5"       
##  [7] "6"        "7"        "8"        "9"        "Diploma"  "Doktor"  
## [13] "Magister" "Sarjana"  "SD"       "SMA"      "SMP"     
## 
## Levels of jenis_pekerjaan :
## [1] "Nelayan"       "Petani"        "PNS"           "Swasta"       
## [5] "Tidak Bekerja" "Wiraswasta"   
## 
## Levels of kepemilikan_rumah :
## [1] "Menumpang"     "Milik Sendiri" "Sewa"         
## 
## Levels of akses_internet :
## [1] "Tidak" "Ya"   
## 
## Levels of jenis_kelamin :
## [1] "Laki-laki" "Perempuan"
## 
## Levels of wilayah :
## [1] "Pedesaan"  "Perkotaan"

Untuk variabel status_perkawinan dan tingkat_pendidikan terdapat inkonsistensi data dimana ada isian yang tidak seharunya yaitu nilai.

head(data.frame(dataset$id,dataset$nama_kepala_rumah_tangga))
##   dataset.id dataset.nama_kepala_rumah_tangga
## 1          1            Kepala Rumah Tangga 1
## 2          2            Kepala Rumah Tangga 2
## 3          3            Kepala Rumah Tangga 3
## 4          4            Kepala Rumah Tangga 4
## 5          5            Kepala Rumah Tangga 5
## 6          6            Kepala Rumah Tangga 6

Dimana id merupakan id rumah tangga sehingga harus di cek konsistensinya nantinya

# Identifikasi variabel numerik
num_vars <- sapply(dataset, is.numeric)

# Loop untuk cek nilai <= 0 per variabel numerik
for (var in names(dataset)[num_vars]) {
  cat("Values <= 0 in", var, ":\n")
  vals <- dataset[[var]][!is.na(dataset[[var]]) & dataset[[var]] <= 0]
  print(unique(vals))
  cat("Count:", length(vals), "\n\n")
}
## Values <= 0 in pendapatan_tahunan :
## [1] -5264050 -3384407 -1599018 -2627989
## Count: 4 
## 
## Values <= 0 in pengeluaran_bulanan :
## numeric(0)
## Count: 0 
## 
## Values <= 0 in jumlah_anggota_keluarga :
## numeric(0)
## Count: 0 
## 
## Values <= 0 in umur_kepala_rumah_tangga :
## numeric(0)
## Count: 0

Dimana ada pendapatan_tahunan yang bernilai negatif yang ini melanggar konsistensi isian yang harus lebih dari 0

Cek Missing Value

colSums(is.na(dataset))
##                       id nama_kepala_rumah_tangga        status_perkawinan 
##                        0                        0                       20 
##       tingkat_pendidikan          jenis_pekerjaan        kepemilikan_rumah 
##                       19                       18                       20 
##           akses_internet            jenis_kelamin                  wilayah 
##                       20                       19                       20 
##       pendapatan_tahunan      pengeluaran_bulanan  jumlah_anggota_keluarga 
##                       20                       20                       20 
## umur_kepala_rumah_tangga 
##                       20
library(skimr)
## Warning: package 'skimr' was built under R version 4.4.3
skim(dataset)
Data summary
Name dataset
Number of rows 999
Number of columns 13
_______________________
Column type frequency:
character 9
numeric 4
________________________
Group variables None

Variable type: character

skim_variable n_missing complete_rate min max empty n_unique whitespace
id 0 1.00 1 4 0 999 0
nama_kepala_rumah_tangga 0 1.00 21 24 0 999 0
status_perkawinan 20 0.98 1 13 0 14 0
tingkat_pendidikan 19 0.98 1 8 0 17 0
jenis_pekerjaan 18 0.98 3 13 0 6 0
kepemilikan_rumah 20 0.98 4 13 0 3 0
akses_internet 20 0.98 2 5 0 2 0
jenis_kelamin 19 0.98 9 9 0 2 0
wilayah 20 0.98 8 9 0 2 0

Variable type: numeric

skim_variable n_missing complete_rate mean sd p0 p25 p50 p75 p100 hist
pendapatan_tahunan 20 0.98 83064128.15 80062249.39 -5264050 41593467 59029706 127832429 1082391430 ▇▁▁▁▁
pengeluaran_bulanan 20 0.98 5457047.34 4705382.41 2035804 4334623 5035425 5720818 67693630 ▇▁▁▁▁
jumlah_anggota_keluarga 20 0.98 5.62 2.94 1 3 6 8 10 ▇▆▇▇▇
umur_kepala_rumah_tangga 20 0.98 49.46 17.61 20 35 49 65 80 ▇▇▇▆▇

Dimana terlihat unutk variabel selain id dan nama_kepala_rumah_tangga terdapat missing value dengan total 216 isian

Data Validation

library(validate)
## 
## Attaching package: 'validate'
## The following object is masked from 'package:dplyr':
## 
##     expr
val<-validator( "id"= is_unique(id)==T,
                "nama_kepala_rumah_tangga"=nama_kepala_rumah_tangga == paste("Kepala Rumah Tangga", id),
                "status_perkawinan"= status_perkawinan %in% c("Belum Menikah","Cerai","Janda/Duda","Menikah"),
                "tingkat_pendidikan"= tingkat_pendidikan %in% c("SD","SMP","SMA","Sarjana","Diploma","Magister","Doktor"),
                "jenis_pekerjaan"= jenis_pekerjaan  %in% c("Nelayan","Petani","PNS","Swasta","Tidak Bekerja","Wiraswasta"),
                "kepemilikan_rumah"=kepemilikan_rumah %in% c("Menumpang","Milik Sendiri","Sewa"),
                "akses_internet"=akses_internet %in% c("Ya","Tidak"),
                "jenis_kelamin"=jenis_kelamin %in% c("Laki-laki","Perempuan"),
                "wilayah"=wilayah %in% c("Pedesaan","Perkotaan"),
                "pendapatan_tahunan"=pendapatan_tahunan>0,
                "pengeluaran_bulanan"=pengeluaran_bulanan>0,
                "jumlah_anggota_keluarga"=jumlah_anggota_keluarga>0,
                "umur_kepala_rumah_tangga"=umur_kepala_rumah_tangga>0
                
                
                )
data_val <- confront(dataset, val, key  ="id")

summary(data_val)
##                        name items passes fails nNA error warning
## 1                        id   999    999     0   0 FALSE   FALSE
## 2  nama_kepala_rumah_tangga   999    999     0   0 FALSE   FALSE
## 3         status_perkawinan   999    950    29  20 FALSE   FALSE
## 4        tingkat_pendidikan   999    932    48  19 FALSE   FALSE
## 5           jenis_pekerjaan   999    981     0  18 FALSE   FALSE
## 6         kepemilikan_rumah   999    979     0  20 FALSE   FALSE
## 7            akses_internet   999    979     0  20 FALSE   FALSE
## 8             jenis_kelamin   999    980     0  19 FALSE   FALSE
## 9                   wilayah   999    979     0  20 FALSE   FALSE
## 10       pendapatan_tahunan   999    975     4  20 FALSE   FALSE
## 11      pengeluaran_bulanan   999    979     0  20 FALSE   FALSE
## 12  jumlah_anggota_keluarga   999    979     0  20 FALSE   FALSE
## 13 umur_kepala_rumah_tangga   999    979     0  20 FALSE   FALSE
##                                                                                      expression
## 1                                                                            is_unique(id) == T
## 2                                  nama_kepala_rumah_tangga == paste("Kepala Rumah Tangga", id)
## 3                  status_perkawinan %vin% c("Belum Menikah", "Cerai", "Janda/Duda", "Menikah")
## 4    tingkat_pendidikan %vin% c("SD", "SMP", "SMA", "Sarjana", "Diploma", "Magister", "Doktor")
## 5  jenis_pekerjaan %vin% c("Nelayan", "Petani", "PNS", "Swasta", "Tidak Bekerja", "Wiraswasta")
## 6                               kepemilikan_rumah %vin% c("Menumpang", "Milik Sendiri", "Sewa")
## 7                                                         akses_internet %vin% c("Ya", "Tidak")
## 8                                               jenis_kelamin %vin% c("Laki-laki", "Perempuan")
## 9                                                      wilayah %vin% c("Pedesaan", "Perkotaan")
## 10                                                                       pendapatan_tahunan > 0
## 11                                                                      pengeluaran_bulanan > 0
## 12                                                                  jumlah_anggota_keluarga > 0
## 13                                                                 umur_kepala_rumah_tangga > 0
plot(data_val)

Sehingga diperoleh banyak data yang inkonsisten dari variabel selain id dan nama_kepala_rumah_tangga sebanyak 81 isian dan missing value sebanyak 216 isian

library(flextable)
# Convert our output into a dataframe first

rb <- as.data.frame(data_val)

# Errors for each record id
Eb <- rb%>%
  filter(! value == T)%>%
  select(id, name, expression)
result <- Eb %>%
  group_by(id) %>%
  summarise(name = paste(unique(name), collapse = " & ")) %>%
  ungroup()

# Tampilkan hasil
print(result)
## # A tibble: 81 × 2
##    id    name              
##    <chr> <chr>             
##  1 113   tingkat_pendidikan
##  2 127   tingkat_pendidikan
##  3 135   status_perkawinan 
##  4 137   tingkat_pendidikan
##  5 143   status_perkawinan 
##  6 151   tingkat_pendidikan
##  7 155   tingkat_pendidikan
##  8 160   tingkat_pendidikan
##  9 211   status_perkawinan 
## 10 212   tingkat_pendidikan
## # ℹ 71 more rows

Terdapat 81 record atau baris yang mengalami missing value atau inkonsistensi

Imputasi Missing Value dan Inkonsisten

Status Perkawinan

library(dplyr)

# Konversi hasil validasi
val_result <- as.data.frame(data_val)

# Ambil ID yang gagal atau NA pada status_perkawinan
invalid_ids_status <- val_result %>%
  filter(name == "status_perkawinan" & (is.na(value) | value == FALSE)) %>%
  pull(id) %>%
  unique()

# Ambil ID yang valid (tidak terlanggar atau NA) untuk keselurhan
valid_ids_status <- val_result %>%
  filter(is.na(value)==F |value == TRUE) %>%
  pull(id) %>%
  unique()

# Fungsi modus
get_modus <- function(x) {
  ux <- unique(x[!is.na(x)])
  ux[which.max(tabulate(match(x, ux)))]
}

# Imputasi berdasarkan tingkat_pendidikan (jika tidak ada, fallback ke jenis_pekerjaan)
for (id in invalid_ids_status) {
  baris <- dataset %>% filter(id == !!id)
  
  if (nrow(baris) == 0) next
  
  pendidikan <- baris$tingkat_pendidikan
  fallback <- baris$jenis_pekerjaan
  modus <- NA
  
  if (!is.na(pendidikan)) {
    valid_status <- dataset %>%
      filter(
        id %in% valid_ids_status,
        tingkat_pendidikan == pendidikan,
        !is.na(status_perkawinan)
      ) %>%
      pull(status_perkawinan)
    
    modus <- get_modus(valid_status)
  }
  
  # Fallback ke jenis_pekerjaan jika modus masih NA
  if (is.na(modus) && !is.na(fallback)) {
    valid_status_fallback <- dataset %>%
      filter(
        id %in% valid_ids_status,
        jenis_pekerjaan == fallback,
        !is.na(status_perkawinan)
      ) %>%
      pull(status_perkawinan)
    
    modus <- get_modus(valid_status_fallback)
  }

  # Imputasi jika modus berhasil ditemukan
  if (!is.na(modus)) {
    dataset$status_perkawinan[dataset$id == id] <- modus
  }
}

Imputasi berdasarkan karakteristik yang mewakili : Variabel acuan utama: tingkat_pendidikan Fallback: jenis_pekerjaan

Misalnya: Jika data status perkawinan seseorang kosong atau tidak valid, maka akan diisi dengan status perkawinan yang paling sering muncul di kelompok orang dengan tingkat pendidikan yang sama. Kalau tidak ditemukan (tidak ada data valid dengan tingkat pendidikan tersebut), maka akan dicari berdasarkan jenis pekerjaan.

Tingkat Pendidikan

# Ambil ID yang gagal atau NA pada tingkat_pendidikan
invalid_ids_pendidikan <- val_result %>%
  filter(name == "tingkat_pendidikan" & (is.na(value) | value == FALSE)) %>%
  pull(id) %>%
  unique()

# Ambil ID yang valid (tidak terlanggar atau NA) untuk keseluruhan
valid_ids_pendidikan <- val_result %>%
  filter(is.na(value)==F |value == TRUE) %>%
  pull(id) %>%
  unique()

# Fungsi modus
get_modus <- function(x) {
  ux <- unique(x[!is.na(x)])
  ux[which.max(tabulate(match(x, ux)))]
}

# Imputasi berdasarkan jenis_pekerjaan (fallback ke status_perkawinan)
for (id in invalid_ids_pendidikan) {
  baris <- dataset %>% filter(id == !!id)
  
  if (nrow(baris) == 0) next
  
  pekerjaan <- baris$jenis_pekerjaan
  fallback <- baris$status_perkawinan
  modus <- NA

  if (!is.na(pekerjaan)) {
    valid_pendidikan <- dataset %>%
      filter(
        id %in% valid_ids_pendidikan,
        jenis_pekerjaan == pekerjaan,
        !is.na(tingkat_pendidikan)
      ) %>%
      pull(tingkat_pendidikan)
    
    modus <- get_modus(valid_pendidikan)
  }

  # Fallback ke status_perkawinan jika modus masih NA
  if (is.na(modus) && !is.na(fallback)) {
    valid_pendidikan_fallback <- dataset %>%
      filter(
        id %in% valid_ids_pendidikan,
        status_perkawinan == fallback,
        !is.na(tingkat_pendidikan)
      ) %>%
      pull(tingkat_pendidikan)
    
    modus <- get_modus(valid_pendidikan_fallback)
  }

  # Imputasi jika modus berhasil ditemukan
  if (!is.na(modus)) {
    dataset$tingkat_pendidikan[dataset$id == id] <- modus
  }
}

Imputasi berdasarkan karakteristik yang mewakili : Variabel acuan utama: jenis_pekerjaan Fallback: status_perkawinan

Misalnya: Jika data tingkat pendidikan seseorang tidak terisi, maka akan diisi dengan tingkat pendidikan yang paling umum di kelompok orang dengan jenis pekerjaan yang sama. Jika tetap tidak ditemukan, maka akan dilihat berdasarkan status perkawinannya. ## Jenis Pekerjaan

# Ambil ID yang gagal atau NA pada jenis_pekerjaan
invalid_ids_pekerjaan <- val_result %>%
  filter(name == "jenis_pekerjaan" & (is.na(value) | value == FALSE)) %>%
  pull(id) %>%
  unique()

# Ambil ID yang valid (tidak terlanggar atau NA) untuk keseluruhan
valid_ids_pekerjaan <- val_result %>%
  filter((is.na(value) == FALSE | value == TRUE)) %>%
  pull(id) %>%
  unique()

# Fungsi modus
get_modus <- function(x) {
  ux <- unique(x[!is.na(x)])
  if (length(ux) == 0) return(NA)
  ux[which.max(tabulate(match(x, ux)))]
}

# Imputasi jenis_pekerjaan berdasarkan tingkat_pendidikan, fallback ke status_perkawinan
for (id in invalid_ids_pekerjaan) {
  baris <- dataset %>% filter(id == !!id)
  
  if (nrow(baris) == 0) next
  
  pendidikan <- baris$tingkat_pendidikan
  fallback <- baris$status_perkawinan
  modus <- NA
  
  # Gunakan tingkat_pendidikan sebagai kriteria utama
  if (!is.na(pendidikan)) {
    valid_pekerjaan <- dataset %>%
      filter(
        id %in% valid_ids_pekerjaan,
        tingkat_pendidikan == pendidikan,
        !is.na(jenis_pekerjaan)
      ) %>%
      pull(jenis_pekerjaan)
    
    modus <- get_modus(valid_pekerjaan)
  }
  
  # Fallback ke status_perkawinan jika modus masih NA
  if (is.na(modus) && !is.na(fallback)) {
    valid_pekerjaan_fallback <- dataset %>%
      filter(
        id %in% valid_ids_pekerjaan,
        status_perkawinan == fallback,
        !is.na(jenis_pekerjaan)
      ) %>%
      pull(jenis_pekerjaan)
    
    modus <- get_modus(valid_pekerjaan_fallback)
  }
  
  # Imputasi jika modus ditemukan
  if (!is.na(modus)) {
    dataset$jenis_pekerjaan[dataset$id == id] <- modus
  }
}

Imputasi berdasarkan karakteristik yang mewakili : Variabel acuan utama: tingkat_pendidikan Fallback: status_perkawinan

Misalnya: Jika jenis pekerjaan seseorang kosong, maka sistem akan mencari jenis pekerjaan yang paling sering muncul pada orang dengan tingkat pendidikan yang sama. Jika tidak ditemukan, akan digunakan data berdasarkan status perkawinan.

Kepemilikan Rumah

# Ambil ID yang gagal atau NA pada kepemilikan_rumah
invalid_ids_rumah <- val_result %>%
  filter(name == "kepemilikan_rumah" & (is.na(value) | value == FALSE)) %>%
  pull(id) %>%
  unique()

# Ambil ID yang valid (tidak terlanggar atau NA) untuk keseluruhan
valid_ids_rumah <- val_result %>%
  filter((is.na(value) == FALSE | value == TRUE)) %>%
  pull(id) %>%
  unique()

# Fungsi modus (tetap sama)
get_modus <- function(x) {
  ux <- unique(x[!is.na(x)])
  if (length(ux) == 0) return(NA)
  ux[which.max(tabulate(match(x, ux)))]
}

# Imputasi kepemilikan_rumah berdasarkan jenis_pekerjaan, fallback ke wilayah
for (id in invalid_ids_rumah) {
  baris <- dataset %>% filter(id == !!id)
  
  if (nrow(baris) == 0) next
  
  pekerjaan <- baris$jenis_pekerjaan
  fallback <- baris$wilayah
  modus <- NA
  
  # Gunakan jenis_pekerjaan sebagai kriteria utama
  if (!is.na(pekerjaan)) {
    valid_rumah <- dataset %>%
      filter(
        id %in% valid_ids_rumah,
        jenis_pekerjaan == pekerjaan,
        !is.na(kepemilikan_rumah)
      ) %>%
      pull(kepemilikan_rumah)
    
    modus <- get_modus(valid_rumah)
  }
  
  # Fallback ke wilayah jika modus masih NA
  if (is.na(modus) && !is.na(fallback)) {
    valid_rumah_fallback <- dataset %>%
      filter(
        id %in% valid_ids_rumah,
        wilayah == fallback,
        !is.na(kepemilikan_rumah)
      ) %>%
      pull(kepemilikan_rumah)
    
    modus <- get_modus(valid_rumah_fallback)
  }
  
  # Imputasi jika modus ditemukan
  if (!is.na(modus)) {
    dataset$kepemilikan_rumah[dataset$id == id] <- modus
  }
}

Imputasi berdasarkan karakteristik yang mewakili : Variabel acuan utama: jenis_pekerjaan Fallback: wilayah

Misalnya: Jika data kepemilikan rumah tidak diisi, maka akan diisi dengan nilai yang paling banyak muncul pada orang dengan jenis pekerjaan yang sama. Jika tidak ditemukan, maka akan dilihat berdasarkan wilayah tempat tinggalnya.

Akses Internet

# Ambil ID yang gagal atau NA pada akses_internet
invalid_ids_internet <- val_result %>%
  filter(name == "akses_internet" & (is.na(value) | value == FALSE)) %>%
  pull(id) %>%
  unique()

# Ambil ID yang valid (tidak terlanggar atau NA) untuk keseluruhan
valid_ids_internet <- val_result %>%
  filter((is.na(value) == FALSE | value == TRUE)) %>%
  pull(id) %>%
  unique()

# Imputasi akses_internet berdasarkan wilayah, fallback ke tingkat_pendidikan
for (id in invalid_ids_internet) {
  baris <- dataset %>% filter(id == !!id)
  
  if (nrow(baris) == 0) next
  
  wilayah <- baris$wilayah
  fallback <- baris$tingkat_pendidikan
  modus <- NA
  
  # Gunakan wilayah sebagai kriteria utama
  if (!is.na(wilayah)) {
    valid_internet <- dataset %>%
      filter(
        id %in% valid_ids_internet,
        wilayah == wilayah,
        !is.na(akses_internet)
      ) %>%
      pull(akses_internet)
    
    modus <- get_modus(valid_internet)
  }
  
  # Fallback ke tingkat_pendidikan jika modus masih NA
  if (is.na(modus) && !is.na(fallback)) {
    valid_internet_fallback <- dataset %>%
      filter(
        id %in% valid_ids_internet,
        tingkat_pendidikan == fallback,
        !is.na(akses_internet)
      ) %>%
      pull(akses_internet)
    
    modus <- get_modus(valid_internet_fallback)
  }
  
  # Imputasi jika modus ditemukan
  if (!is.na(modus)) {
    dataset$akses_internet[dataset$id == id] <- modus
  }
}

Imputasi berdasarkan karakteristik yang mewakili : Variabel acuan utama: wilayah Fallback: tingkat_pendidikan

Misalnya: Jika data akses internet kosong, maka akan diisi dengan akses internet yang paling umum pada orang dari wilayah yang sama. Kalau tidak ada, akan dilihat berdasarkan tingkat pendidikan.

Jenis Kelamin

# Ambil ID yang gagal atau NA pada jenis_kelamin
invalid_ids_kelamin <- val_result %>%
  filter(name == "jenis_kelamin" & (is.na(value) | value == FALSE)) %>%
  pull(id) %>%
  unique()

# Ambil ID yang valid (tidak terlanggar atau NA) untuk keseluruhan
valid_ids_kelamin <- val_result %>%
  filter((is.na(value) == FALSE | value == TRUE)) %>%
  pull(id) %>%
  unique()

# Imputasi jenis_kelamin berdasarkan jenis_pekerjaan, fallback ke status_perkawinan
for (id in invalid_ids_kelamin) {
  baris <- dataset %>% filter(id == !!id)
  
  if (nrow(baris) == 0) next
  
  pekerjaan <- baris$jenis_pekerjaan
  fallback <- baris$status_perkawinan
  modus <- NA
  
  # Gunakan jenis_pekerjaan sebagai kriteria utama
  if (!is.na(pekerjaan)) {
    valid_kelamin <- dataset %>%
      filter(
        id %in% valid_ids_kelamin,
        jenis_pekerjaan == pekerjaan,
        !is.na(jenis_kelamin)
      ) %>%
      pull(jenis_kelamin)
    
    modus <- get_modus(valid_kelamin)
  }
  
  # Fallback ke status_perkawinan jika modus masih NA
  if (is.na(modus) && !is.na(fallback)) {
    valid_kelamin_fallback <- dataset %>%
      filter(
        id %in% valid_ids_kelamin,
        status_perkawinan == fallback,
        !is.na(jenis_kelamin)
      ) %>%
      pull(jenis_kelamin)
    
    modus <- get_modus(valid_kelamin_fallback)
  }
  
  # Imputasi jika modus ditemukan
  if (!is.na(modus)) {
    dataset$jenis_kelamin[dataset$id == id] <- modus
  }
}

Imputasi berdasarkan karakteristik yang mewakili : Variabel acuan utama: jenis_pekerjaan Fallback: status_perkawinan

Misalnya: Jika data jenis kelamin tidak terisi, maka akan dicari jenis kelamin yang paling sering muncul pada orang dengan jenis pekerjaan yang sama. Kalau tidak ketemu, maka akan dilihat berdasarkan status perkawinan.

Wilayah

# Ambil ID yang gagal atau NA pada wilayah
invalid_ids_wilayah <- val_result %>%
  filter(name == "wilayah" & (is.na(value) | value == FALSE)) %>%
  pull(id) %>%
  unique()

# Ambil ID yang valid (tidak terlanggar atau NA) untuk keseluruhan
valid_ids_wilayah <- val_result %>%
  filter((is.na(value) == FALSE | value == TRUE)) %>%
  pull(id) %>%
  unique()

# Imputasi wilayah berdasarkan akses_internet, fallback ke jenis_pekerjaan
for (id in invalid_ids_wilayah) {
  baris <- dataset %>% filter(id == !!id)
  
  if (nrow(baris) == 0) next
  
  akses_internet <- baris$akses_internet
  fallback <- baris$jenis_pekerjaan
  modus <- NA
  
  # Gunakan akses_internet sebagai kriteria utama
  if (!is.na(akses_internet)) {
    valid_wilayah <- dataset %>%
      filter(
        id %in% valid_ids_wilayah,
        akses_internet == akses_internet,
        !is.na(wilayah)
      ) %>%
      pull(wilayah)
    
    modus <- get_modus(valid_wilayah)
  }
  
  # Fallback ke jenis_pekerjaan jika modus masih NA
  if (is.na(modus) && !is.na(fallback)) {
    valid_wilayah_fallback <- dataset %>%
      filter(
        id %in% valid_ids_wilayah,
        jenis_pekerjaan == fallback,
        !is.na(wilayah)
      ) %>%
      pull(wilayah)
    
    modus <- get_modus(valid_wilayah_fallback)
  }
  
  # Imputasi jika modus ditemukan
  if (!is.na(modus)) {
    dataset$wilayah[dataset$id == id] <- modus
  }
}

Imputasi berdasarkan karakteristik yang mewakili : Variabel acuan utama: akses_internet Fallback: jenis_pekerjaan

Misalnya: Jika data wilayah tidak tersedia, maka akan diisi dengan wilayah yang paling umum pada orang yang memiliki status akses internet yang sama. Jika tidak ketemu, maka akan dilihat berdasarkan jenis pekerjaan.

Pendapatan Tahunan

# Ambil ID yang gagal atau NA pada pendapatan_tahunan
invalid_ids_pendapatan <- val_result %>%
  filter(name == "pendapatan_tahunan" & (is.na(value) | value == FALSE)) %>%
  pull(id) %>%
  unique()

# Ambil ID yang valid (tidak terlanggar atau NA) untuk keseluruhan
valid_ids_pendapatan <- val_result %>%
  filter((is.na(value) == FALSE | value == TRUE)) %>%
  pull(id) %>%
  unique()

# Fungsi untuk menghitung rata-rata dengan 0 digit di belakang koma
get_mean <- function(x) {
  mean(x, na.rm = TRUE)
}

# Imputasi pendapatan_tahunan berdasarkan jenis_pekerjaan, fallback ke tingkat_pendidikan
for (id in invalid_ids_pendapatan) {
  baris <- dataset %>% filter(id == !!id)
  
  if (nrow(baris) == 0) next
  
  pekerjaan <- baris$jenis_pekerjaan
  fallback <- baris$tingkat_pendidikan
  imputasi_value <- NA
  
  # Gunakan jenis_pekerjaan sebagai kriteria utama
  if (!is.na(pekerjaan)) {
    valid_pendapatan <- dataset %>%
      filter(
        id %in% valid_ids_pendapatan,
        jenis_pekerjaan == pekerjaan,
        !is.na(pendapatan_tahunan)
      ) %>%
      pull(pendapatan_tahunan)
    
    imputasi_value <- get_mean(valid_pendapatan)
  }
  
  # Fallback ke tingkat_pendidikan jika rata-rata masih NA
  if (is.na(imputasi_value) && !is.na(fallback)) {
    valid_pendapatan_fallback <- dataset %>%
      filter(
        id %in% valid_ids_pendapatan,
        tingkat_pendidikan == fallback,
        !is.na(pendapatan_tahunan)
      ) %>%
      pull(pendapatan_tahunan)
    
    imputasi_value <- get_mean(valid_pendapatan_fallback)
  }
  
  # Imputasi jika rata-rata berhasil ditemukan
  if (!is.na(imputasi_value)) {
    dataset$pendapatan_tahunan[dataset$id == id] <- round(imputasi_value, 0)
  }
}

Imputasi berdasarkan karakteristik yang mewakili : Variabel acuan utama: jenis_pekerjaan Fallback: tingkat pendidikan

Misalnya: Bila jumlah_pendapatan kosong, maka sistem akan mengisi dengan rata-rata pendapatan dari orang yang memiliki pekerjaan yang sama. Kalau tidak ditemukan, akan dicari rata-rata berdasarkan tingkat pendidikan.

Pengeluaran Bulanan

# Ambil ID yang gagal atau NA pada pengeluaran_bulanan
invalid_ids_pengeluaran <- val_result %>%
  filter(name == "pengeluaran_bulanan" & (is.na(value) | value == FALSE)) %>%
  pull(id) %>%
  unique()

# Ambil ID yang valid (tidak terlanggar atau NA) untuk keseluruhan
valid_ids_pengeluaran <- val_result %>%
  filter((is.na(value) == FALSE | value == TRUE)) %>%
  pull(id) %>%
  unique()

# Fungsi untuk menghitung rata-rata dengan 0 digit di belakang koma
get_mean <- function(x) {
  mean(x, na.rm = TRUE)
}

# Imputasi pengeluaran_bulanan berdasarkan jenis_pekerjaan, fallback ke kepemilikan_rumah
for (id in invalid_ids_pengeluaran) {
  baris <- dataset %>% filter(id == !!id)
  
  if (nrow(baris) == 0) next
  
  pekerjaan <- baris$jenis_pekerjaan
  kepemilikan <- baris$kepemilikan_rumah
  imputasi_value <- NA
  
  # Gunakan jenis_pekerjaan sebagai kriteria utama
  if (!is.na(pekerjaan)) {
    valid_pengeluaran <- dataset %>%
      filter(
        id %in% valid_ids_pengeluaran,
        jenis_pekerjaan == pekerjaan,
        !is.na(pengeluaran_bulanan)
      ) %>%
      pull(pengeluaran_bulanan)
    
    imputasi_value <- get_mean(valid_pengeluaran)
  }
  
  # Fallback ke kepemilikan_rumah jika rata-rata masih NA
  if (is.na(imputasi_value) && !is.na(kepemilikan)) {
    valid_pengeluaran_fallback <- dataset %>%
      filter(
        id %in% valid_ids_pengeluaran,
        kepemilikan_rumah == kepemilikan,
        !is.na(pengeluaran_bulanan)
      ) %>%
      pull(pengeluaran_bulanan)
    
    imputasi_value <- get_mean(valid_pengeluaran_fallback)
  }
  
  # Imputasi jika rata-rata berhasil ditemukan
  if (!is.na(imputasi_value)) {
    dataset$pengeluaran_bulanan[dataset$id == id] <- round(imputasi_value, 0)
  }
}

Imputasi berdasarkan karakteristik yang mewakili : Variabel acuan utama: jenis_pekerjaan Fallback: kepemilikan_rumah

Misalnya: Jika jumlah_pengeluaran tidak ada, maka nilai akan diisi dengan rata-rata jumlah_pengeluaran dari kelompok orang yang memiliki jenis pekerjaan yang sama. Jika tetap tidak ditemukan, maka digunakan rata-rata berdasarkan kepemilikan_rumah.

Jumlah ART

# Ambil ID yang gagal atau NA pada jumlah_anggota_keluarga
invalid_ids_anggota_keluarga <- val_result %>%
  filter(name == "jumlah_anggota_keluarga" & (is.na(value) | value == FALSE)) %>%
  pull(id) %>%
  unique()

# Ambil ID yang valid (tidak terlanggar atau NA) untuk keseluruhan
valid_ids_anggota_keluarga <- val_result %>%
  filter( (is.na(value) == FALSE | value == TRUE)) %>%
  pull(id) %>%
  unique()

# Fungsi untuk menghitung rata-rata dengan 0 digit di belakang koma
get_mean <- function(x) {
  mean(x, na.rm = TRUE)
}

# Imputasi jumlah_anggota_keluarga berdasarkan status_perkawinan, fallback ke kepemilikan_rumah
for (id in invalid_ids_anggota_keluarga) {
  baris <- dataset %>% filter(id == !!id)
  
  if (nrow(baris) == 0) next
  
  status_perkawinan <- baris$status_perkawinan
  kepemilikan <- baris$kepemilikan_rumah
  imputasi_value <- NA
  
  # Gunakan status_perkawinan sebagai kriteria utama
  if (!is.na(status_perkawinan)) {
    valid_anggota <- dataset %>%
      filter(
        id %in% valid_ids_anggota_keluarga,
        status_perkawinan == status_perkawinan,
        !is.na(jumlah_anggota_keluarga)
      ) %>%
      pull(jumlah_anggota_keluarga)
    
    imputasi_value <- get_mean(valid_anggota)
  }
  
  # Fallback ke kepemilikan_rumah jika rata-rata masih NA
  if (is.na(imputasi_value) && !is.na(kepemilikan)) {
    valid_anggota_fallback <- dataset %>%
      filter(
        id %in% valid_ids_anggota_keluarga,
        kepemilikan_rumah == kepemilikan,
        !is.na(jumlah_anggota_keluarga)
      ) %>%
      pull(jumlah_anggota_keluarga)
    
    imputasi_value <- get_mean(valid_anggota_fallback)
  }
  
  # Imputasi jika rata-rata berhasil ditemukan
  if (!is.na(imputasi_value)) {
    dataset$jumlah_anggota_keluarga[dataset$id == id] <- round(imputasi_value, 0)
  }
}

Imputasi berdasarkan karakteristik yang mewakili : Variabel acuan utama: status_perkawinan Fallback: kepemilikan_rumah

Misalnya: Kalau jumlah art tidak terisi, maka akan diisi dengan rata-rata jumlah tanggungan dari orang yang memiliki status perkawinan yang sama. Jika tidak ditemukan, fallback ke kepemilikan_rumah

Umur KRT

# Ambil ID yang gagal atau NA pada umur_kepala_rumah_tangga
invalid_ids_umur <- val_result %>%
  filter(name == "umur_kepala_rumah_tangga" & (is.na(value) | value == FALSE)) %>%
  pull(id) %>%
  unique()

# Ambil ID yang valid (tidak terlanggar atau NA) untuk keseluruhan
valid_ids_umur <- val_result %>%
  filter((is.na(value) == FALSE | value == TRUE)) %>%
  pull(id) %>%
  unique()

# Fungsi untuk menghitung rata-rata dengan 0 digit di belakang koma
get_mean <- function(x) {
  mean(x, na.rm = TRUE)
}

# Imputasi umur_kepala_rumah_tangga berdasarkan kepemilikan_rumah, fallback ke wilayah
for (id in invalid_ids_umur) {
  baris <- dataset %>% filter(id == !!id)
  
  if (nrow(baris) == 0) next
  
  kepemilikan <- baris$kepemilikan_rumah
  wilayah <- baris$wilayah
  imputasi_value <- NA
  
  # Gunakan kepemilikan_rumah sebagai kriteria utama
  if (!is.na(kepemilikan)) {
    valid_umur <- dataset %>%
      filter(
        id %in% valid_ids_umur,
        kepemilikan_rumah == kepemilikan,
        !is.na(umur_kepala_rumah_tangga)
      ) %>%
      pull(umur_kepala_rumah_tangga)
    
    imputasi_value <- get_mean(valid_umur)
  }
  
  # Fallback ke wilayah jika rata-rata masih NA
  if (is.na(imputasi_value) && !is.na(wilayah)) {
    valid_umur_fallback <- dataset %>%
      filter(
        id %in% valid_ids_umur,
        wilayah == wilayah,
        !is.na(umur_kepala_rumah_tangga)
      ) %>%
      pull(umur_kepala_rumah_tangga)
    
    imputasi_value <- get_mean(valid_umur_fallback)
  }
  
  # Imputasi jika rata-rata berhasil ditemukan
  if (!is.na(imputasi_value)) {
    dataset$umur_kepala_rumah_tangga[dataset$id == id] <- round(imputasi_value, 0)
  }
}

Imputasi berdasarkan karakteristik yang mewakili : Variabel acuan utama: kepemilikan rumah

Fallback: wilayah

Misalnya: Jika usia kosong, maka diisi dengan rata-rata usia pada kelompok dengan kepemilikan rumah yang sama. Kalau tidak ada, digunakan rata-rata berdasarkan wilayah.

data_val <- confront(dataset, val, key  ="id")

summary(data_val)
##                        name items passes fails nNA error warning
## 1                        id   999    999     0   0 FALSE   FALSE
## 2  nama_kepala_rumah_tangga   999    999     0   0 FALSE   FALSE
## 3         status_perkawinan   999    999     0   0 FALSE   FALSE
## 4        tingkat_pendidikan   999    999     0   0 FALSE   FALSE
## 5           jenis_pekerjaan   999    999     0   0 FALSE   FALSE
## 6         kepemilikan_rumah   999    999     0   0 FALSE   FALSE
## 7            akses_internet   999    999     0   0 FALSE   FALSE
## 8             jenis_kelamin   999    999     0   0 FALSE   FALSE
## 9                   wilayah   999    999     0   0 FALSE   FALSE
## 10       pendapatan_tahunan   999    999     0   0 FALSE   FALSE
## 11      pengeluaran_bulanan   999    999     0   0 FALSE   FALSE
## 12  jumlah_anggota_keluarga   999    999     0   0 FALSE   FALSE
## 13 umur_kepala_rumah_tangga   999    999     0   0 FALSE   FALSE
##                                                                                      expression
## 1                                                                            is_unique(id) == T
## 2                                  nama_kepala_rumah_tangga == paste("Kepala Rumah Tangga", id)
## 3                  status_perkawinan %vin% c("Belum Menikah", "Cerai", "Janda/Duda", "Menikah")
## 4    tingkat_pendidikan %vin% c("SD", "SMP", "SMA", "Sarjana", "Diploma", "Magister", "Doktor")
## 5  jenis_pekerjaan %vin% c("Nelayan", "Petani", "PNS", "Swasta", "Tidak Bekerja", "Wiraswasta")
## 6                               kepemilikan_rumah %vin% c("Menumpang", "Milik Sendiri", "Sewa")
## 7                                                         akses_internet %vin% c("Ya", "Tidak")
## 8                                               jenis_kelamin %vin% c("Laki-laki", "Perempuan")
## 9                                                      wilayah %vin% c("Pedesaan", "Perkotaan")
## 10                                                                       pendapatan_tahunan > 0
## 11                                                                      pengeluaran_bulanan > 0
## 12                                                                  jumlah_anggota_keluarga > 0
## 13                                                                 umur_kepala_rumah_tangga > 0
plot(data_val)

Setelah dilakukan imputasi unutk isian yang inkonsisten maupun missing value di dapatkan data clean yang siap untuk dilakukan analisis

Data Clean

library(skimr)

skim(dataset)
Data summary
Name dataset
Number of rows 999
Number of columns 13
_______________________
Column type frequency:
character 9
numeric 4
________________________
Group variables None

Variable type: character

skim_variable n_missing complete_rate min max empty n_unique whitespace
id 0 1 1 4 0 999 0
nama_kepala_rumah_tangga 0 1 21 24 0 999 0
status_perkawinan 0 1 5 13 0 4 0
tingkat_pendidikan 0 1 2 8 0 7 0
jenis_pekerjaan 0 1 3 13 0 6 0
kepemilikan_rumah 0 1 4 13 0 3 0
akses_internet 0 1 2 5 0 2 0
jenis_kelamin 0 1 9 9 0 2 0
wilayah 0 1 8 9 0 2 0

Variable type: numeric

skim_variable n_missing complete_rate mean sd p0 p25 p50 p75 p100 hist
pendapatan_tahunan 0 1 83421102.81 79072428.82 1562596 42305633 60681967 126095168 1082391430 ▇▁▁▁▁
pengeluaran_bulanan 0 1 5458434.07 4658291.18 2035804 4358580 5062174 5736625 67693630 ▇▁▁▁▁
jumlah_anggota_keluarga 0 1 5.63 2.91 1 3 6 8 10 ▇▆▇▇▇
umur_kepala_rumah_tangga 0 1 49.46 17.43 20 35 49 65 80 ▇▇▇▆▆

Dimana pengecekan terakhir data sudah benar-benar clean dan siap dilakukan analisis