Kebiasaan Inspeksi

Mengenali data yang baru diimpor dengan glimpse, summary, str, dan head.

Daftar isi

Data yang baru diimpor belum layak dianalisis. Tipe kolom yang salah, nilai ekstrem, dan baris duplikat sering lolos tanpa error, padahal ketiganya mengubah hasil perhitungan. Kebiasaan menginspeksi data sebelum menganalisis menjadi penyaring pertama, dan R menyediakan sekumpulan fungsi ringan untuk itu, yaitu glimpse(), head(), tail(), summary(), str(), serta penghitung dimensi. Seluruh contoh berjalan pada data yang diimpor dengan read_csv di awal topik, dan setiap fungsi hanya membutuhkan data yang sudah berada di memori.

Data contoh dan impor ulang#

Berkas survei.csv dibangun dari R dan sengaja mengandung tiga keanehan, yaitu satu berat badan yang hilang, satu tinggi badan 17.5 akibat titik desimal yang bergeser, dan satu baris duplikat. Ketiganya mewakili masalah yang biasa ditemukan pada data nyata.

r Mengimpor data contoh dengan read_csv
library(tidyverse)
survei <- tribble(
  ~id, ~nama,   ~umur, ~tinggi, ~berat,
  1,   "Ali",   25,    171,     65,
  2,   "Budi",  31,    168,     72,
  3,   "Citra", 28,    160,     54,
  4,   "Dewi",  35,    155,     49,
  5,   "Eka",   29,    165,     NA,
  6,   "Fajar", 27,    170,     63,
  7,   "Gita",  33,    158,     51,
  8,   "Hana",  30,    17.5,    55,
  9,   "Indra", 26,    164,     60,
  3,   "Citra", 28,    160,     54
)
write_csv(survei, "survei.csv")
survei <- read_csv("survei.csv", show_col_types = FALSE)
survei
text Keluaran
── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
✔ dplyr     1.2.1     ✔ readr     2.2.0
✔ forcats   1.0.1     ✔ stringr   1.6.0
✔ ggplot2   4.0.3     ✔ tibble    3.3.1
✔ lubridate 1.9.5     ✔ tidyr     1.3.2
✔ purrr     1.2.2     
── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag()    masks stats::lag()
ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
# A tibble: 10 × 5
      id nama   umur tinggi berat
   <dbl> <chr> <dbl>  <dbl> <dbl>
 1     1 Ali      25  171      65
 2     2 Budi     31  168      72
 3     3 Citra    28  160      54
 4     4 Dewi     35  155      49
 5     5 Eka      29  165      NA
 6     6 Fajar    27  170      63
 7     7 Gita     33  158      51
 8     8 Hana     30   17.5    55
 9     9 Indra    26  164      60
10     3 Citra    28  160      54

Tibble dengan sepuluh baris dan lima kolom kini berada di memori. Pemuatan tidyverse pada blok yang sama menyediakan tribble(), read_csv(), dan write_csv() yang dipakai sepanjang topik. Pada tampilan pertama, NA pada baris Eka dan angka 17.5 pada baris Hana sudah terlihat, tetapi baris duplikatnya tidak. Inspeksi yang terarah dibutuhkan untuk menemukan semuanya.

Orientasi pertama dengan glimpse#

glimpse() adalah fungsi pertama yang dipanggil pada data baru. Tampilannya transpos, yaitu setiap kolom menjadi satu baris yang memuat nama, tipe, dan sebagian nilainya. Bentuk ini tetap terbaca meskipun data punya puluhan kolom, karena tidak perlu bergulir ke samping seperti tampilan cetak tibble biasa.

r Orientasi vertikal dengan glimpse
glimpse(survei)
text Keluaran
Rows: 10
Columns: 5
$ id     <dbl> 1, 2, 3, 4, 5, 6, 7, 8, 9, 3
$ nama   <chr> "Ali", "Budi", "Citra", "Dewi", "Eka", "Fajar", "Gita", "Hana",…
$ umur   <dbl> 25, 31, 28, 35, 29, 27, 33, 30, 26, 28
$ tinggi <dbl> 171.0, 168.0, 160.0, 155.0, 165.0, 170.0, 158.0, 17.5, 164.0, 1…
$ berat  <dbl> 65, 72, 54, 49, NA, 63, 51, 55, 60, 54

Dari keluaran itu diketahui lima kolom bertipe dbl atau chr, sepuluh baris data, dan nilai kolom nama yang terpotong dengan tanda elipsis. Tipe per kolom inilah yang paling sering salah ditebak saat impor, sehingga pemeriksannya lebih dahulu menghemat pencarian kesalahan di kemudian hari. glimpse() juga bersifat generik, sehingga fungsi yang sama dapat dipanggil pada list, model, dan objek hasil komputasi lainnya tanpa cara pemanggilan yang berbeda.

head, tail, dan dimensi#

head() menampilkan enam baris pertama secara default dan tail() menampilkan enam baris terakhirnya, sementara nrow() dan ncol() menghitung banyaknya baris dan kolom, dan names() mendaftar nama kolomnya. Baris terakhir sering menyimpan kejutan berupa baris duplikat hasil penggabungan berkas, sehingga tail() sama pentingnya dengan head().

r Melihat ujung data dan dimensinya
head(survei)
tail(survei)
nrow(survei)
ncol(survei)
names(survei)
text Keluaran
# A tibble: 6 × 5
     id nama   umur tinggi berat
  <dbl> <chr> <dbl>  <dbl> <dbl>
1     1 Ali      25    171    65
2     2 Budi     31    168    72
3     3 Citra    28    160    54
4     4 Dewi     35    155    49
5     5 Eka      29    165    NA
6     6 Fajar    27    170    63
# A tibble: 6 × 5
     id nama   umur tinggi berat
  <dbl> <chr> <dbl>  <dbl> <dbl>
1     5 Eka      29  165      NA
2     6 Fajar    27  170      63
3     7 Gita     33  158      51
4     8 Hana     30   17.5    55
5     9 Indra    26  164      60
6     3 Citra    28  160      54
[1] 10
[1] 5
[1] "id"     "nama"   "umur"   "tinggi" "berat" 

Dari keluaran tersebut, tail() memperlihatkan baris ke-10 yang isinya persis sama dengan baris Citra di awal data, dan names() mengonfirmasi lima nama kolom sesuai rancangan. Apabila nama kolom dari sumber lainnya memuat spasi atau karakter aneh, pemeriksaan ini menampakkannya sebelum nama tersebut dipakai dalam kode. Sebagai pelengkap, dim() mengembalikan keduanya sekaligus dalam satu vektor berurutan baris lalu kolom, sehingga cocok dipanggil di dalam pesan catatan atau pengecekan otomatis.

Ringkasan angka dan struktur#

summary() menghitung ringkasan statistik per kolom, yaitu minimum, kuartil, median, rata-rata, dan maksimum untuk kolom numerik, serta panjang dan kelas untuk kolom character. Nilai ekstrem langsung terlihat pada baris Min. dan Max., sedangkan baris NA’s menghitung kekosongan.

r Ringkasan statistik dengan summary
summary(survei)
text Keluaran
       id           nama                umur           tinggi     
 Min.   :1.00   Length:10          Min.   :25.00   Min.   : 17.5  
 1st Qu.:3.00   Class :character   1st Qu.:27.25   1st Qu.:158.5  
 Median :4.50   Mode  :character   Median :28.50   Median :162.0  
 Mean   :4.80                      Mean   :29.20   Mean   :148.8  
 3rd Qu.:6.75                      3rd Qu.:30.75   3rd Qu.:167.2  
 Max.   :9.00                      Max.   :35.00   Max.   :171.0  
                                                                  
     berat      
 Min.   :49.00  
 1st Qu.:54.00  
 Median :55.00  
 Mean   :58.11  
 3rd Qu.:63.00  
 Max.   :72.00  
 NA's   :1      

Dua hal menonjol dari keluaran itu. Minimum tinggi badan 17.5 berada jauh di bawah rentang manusia dewasa, sedangkan kolom berat mencatat NA’s sebesar 1. Keduanya persis sesuai dengan keanehan yang ditanam pada data contoh. Untuk kolom faktor, summary() menampilkan frekuensi tiap tingkatnya, sehingga pola pemeriksaan yang sama berlanjut begitu data kategorikal terlibat.

str() menampilkan struktur internal objek, bukan hanya data framenya, yaitu banyaknya observasi, tipe tiap kolom, dan atribut yang melekat. Pada hasil berikut, atribut spec dari readr ikut tercetak karena tersimpan pada objek hasil read_csv().

r Struktur objek dengan str
str(survei)
text Keluaran
spc_tbl_ [10 × 5] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
 $ id    : num [1:10] 1 2 3 4 5 6 7 8 9 3
 $ nama  : chr [1:10] "Ali" "Budi" "Citra" "Dewi" ...
 $ umur  : num [1:10] 25 31 28 35 29 27 33 30 26 28
 $ tinggi: num [1:10] 171 168 160 155 165 170 158 17.5 164 160
 $ berat : num [1:10] 65 72 54 49 NA 63 51 55 60 54
 - attr(*, "spec")=
  .. cols(
  ..   id = col_double(),
  ..   nama = col_character(),
  ..   umur = col_double(),
  ..   tinggi = col_double(),
  ..   berat = col_double()
  .. )
 - attr(*, "problems")=<externalptr> 

Karena sifatnya generik, str() juga bekerja pada list, model, dan objek lainnya, sehingga kebiasaannya terbawa ke seluruh pekerjaan R. Untuk tibble, glimpse() biasanya lebih nyaman dipakai, sedangkan str() lebih teliti karena atribut tersembunyi ikut ditampilkan.

Pemeriksaan yang menjadi kebiasaan#

Tiga pemeriksaan singkat menutup kebiasaan ini, yaitu menghitung nilai hilang dengan sum(is.na()), menghitung baris duplikat dengan sum(duplicated()), dan menampilkan baris dengan nilai ekstrem lewat pengindeksan which.min() atau which.max().

r Memeriksa nilai hilang, duplikat, dan nilai ekstrem
sum(is.na(survei$berat))
sum(duplicated(survei))
survei[which.min(survei$tinggi), ]
text Keluaran
[1] 1
[1] 1
# A tibble: 1 × 5
     id nama   umur tinggi berat
  <dbl> <chr> <dbl>  <dbl> <dbl>
1     8 Hana     30   17.5    55

Keluarannya menjawab tiga hal sekaligus, yaitu satu nilai berat hilang, satu baris duplikat ada, dan tinggi badan terendah milik Hana. Tindak lanjutnya mengikuti konteks analisis, misalnya baris duplikat dibuang dengan distinct(), nilai hilang ditangani sesuai pertanyaan analisis, dan baris 17.5 dikonfirmasi ke sumber data sebelum dikoreksi. Urutan pemeriksaannya boleh berbeda-beda, tetapi yang menentukan adalah kebiasaannya: setiap tabel yang baru tiba melewati pemeriksaan yang sama sebelum langkah analisis berikutnya dijalankan.

Ringkasan#

  • glimpse() menjadi orientasi pertama karena menampilkan tipe setiap kolom dalam bentuk transpos, ditemani head(), tail(), nrow(), ncol(), dan names() untuk melihat isi dan dimensi.
  • summary() menonjolkan nilai ekstrem dan kekosongan, sedangkan str() membongkar struktur dan atribut objek.
  • Pemeriksaan sum(is.na()), sum(duplicated()), dan pengindeksan which.min() atau which.max() menemukan masalah data sebelum analisis dimulai.

Referensi#