Menyiapkan Data
Pekerjaan Di Balik Layar
- Menyiapkan data (data cleaning) sering menjadi pekerjaan paling memakan waktu
- Metode menyiapkan data jarang diajarkan dalam kelas
- Padahal kesalahan dalam menyiapkan data bisa mengubah hasil analisis
Memuat data dari file ke R
Dengan library rio
, kita bisa mengimpor ke R data dari berbagai macam format: txt
, csv
, xls
, xlsx
, dbf
, sav
, dta
, sas7.bdat
. Data yang diimpor akan menjadi obyek R tipe data.frame
.
Install dulu package rio
jika belum pernah diinstal sebelumnya. Muat package tersebut dengan perintah library
# install.packages('rio')
library(rio)
datakab = import('https://raw.githubusercontent.com/msaidf/statek/master/content/indo-dapoer_data.csv')
Mengecek Data
Tampilkan keseluruhan data dengan mengenter nama obyek data. Namun untuk data yang besar, ini tidak banyak membantu bahkan bisa makan waktu lama.
datakab
Perlu dibiasakan untuk mengecek dulu jumlah baris dari tabel data
nrow(datakab)
Gunakan head
dan tail
untuk menampilkan n
baris teratas dan terbawah
head(datakab, n = 3)
n
adalah argumen opsional
tail(datakab)
Lima baris terakhir tabel bukan merupakan data, sehingga perlu kita keluarkan. Kita bisa gunakan indeks positif untuk memilih baris yang dipertahankan,
tail(datakab[1:12012,], 2)
atau gunakan indeks negatif untuk memilih baris yang dibuang.
R memproses fungsi dari dalam ke luar. Namun penulisan seperti ini sulit dibaca dan diikuti urutan prosesnya. Karenanya, kini pemrograman R banyak menggunakan operator piping
%>%
dari librarymagrittr
.f() %>% g()
berarti output dari fungsif
akan menjadi argumen pertama dari fungsig
library(magrittr)
datakab[-12013:-12017,] %>% tail(3)
Subset juga bisa dibuat dengan memfilter tabel data agar hanya memberikan baris yang nilai variabelnya memenuhi kriteria yang ditetapkan. Kita bisa gunakan fungsi which
untuk menghasilkan indeks baris yang memenuhi kriteria tersebut.
- Tanda titik dalam fungsi subset
[.,]
digunakan untuk memandu operator pipe bahwa input dari fungsi sebelumnya menjadi argumen di lokasi titik tersebut$
digunakan untuk memilih kolom/variabelSeries Code
yang merupakan komponen dari tabeldatakab
- nama variabel perlu diapit dengan backtick (```) hanya jika mengandung spasi
which(datakab$`Series Code` != "") %>% datakab[.,] %>% tail(2)
Cara lain untuk memilih baris berdasar kriteria adalah menggunakan fungsi filter
dari library dplyr
.
- Kita bisa menggunakan fungsi dari suatu library tanpa memuatnya terlebih dulu dengan menggunakan
::
- Bandingkan hasil perintah di bawah jika dijalankan tanpa awalan
dplyr::
- Perbedaan tersebut terjadi karena fungsi
filter
yang digunakan berasal dari package lain- Jika ada lebih dari satu fungsi yang bernama sama, R akan memprioritaskan fungsi dari library yang dimuat paling akhir.
dplyr::filter(datakab, `Series Code` != "") %>% tail(2)
Jika sudah yakin indeks menghasilkan subset yang diinginkan, simpan subset tersebut menjadi objek. Jangan sertakan tail
karena yang ingin disimpan adalah keseluruhan data, bukan cuma baris terbawah saja.
datakab = dplyr::filter(datakab, `Series Code` != "")
Memilih variabel
Seperti memilih baris, kita bisa memilih variabel menggunakan indeks kolom yang terletak setelah koma di fungsi subset []
c(1, 3:5, ncol(datakab)) %>% datakab[, .] %>% tail(4)
Indeks kolom angka bisa digantikan dengan vektor nama variabel
datakab[,c('Region Code', 'Series Name')] %>% tail
Pemilihan variabel juga bisa menggunakan dplyr::select
. Namun kali ini lebih baik dplyr
dimuat dulu agar semua fungsi pembantunya bisa ikut digunakan.
Ketika memuat
dplyr
akan ada pesan peringatan fungsi-fungsi dari package lain yang ditutupi oleh fungsi-fungsidplyr
. Fungsidplyr
itu sendiri akan berjalan baik, tapi penggunaan fungsi yang ditutupi kini perlu menyertakan prefix package asalnya.
library(dplyr)
Berapa ketentuan dalam pemilihan variabel di fungsi select
:
- Nama variabel yang mengandung spasi harus diapit tanda kutip
- Pilih sejumlah variabel yang berurutan cukup sebutkan variabel di pinggir,
var_kiri:var_kanan
- Pilih semua variabel yang namanya memiliki kesamaan pola, baik diawali (
starts_with
), diakhiri (ends_with
), atau mengandung (contains
) karakter tertentu - Gunakan tanda minus (
-
) untuk mengecualikan variabel - Urutan kolom tabel baru mengikuti urutan variabel dalam
select
- Mengganti nama variabel yang dipilih,
nama_baru = nama_lama
select(datakab, 'Region Code':'Series Code', -'Series Name',
region_name = 'Region Name', contains('YR'), -contains('YR201')) %>% tail(4)
Merubah Nama Variabel
Jika hanya ingin mengganti nama sejumlah variabel, tanpa merubah struktur tabel data, gunakan dplyr::rename
hasil dari
rename
adalah tabel data, sehingga bisa langsung disubset dengan[]
tanpa menggunakan piping%>%
rename(datakab, region_name = 'Region Name', series_code = 'Series Code') [100:102,]
Merubah nama bisa pula dilakukan dengan meng-assign vektor nama baru dengan panjang sama seperti nama yang hendak digantikan
names(datakab)[1:3] = names(datakab)[1:3] %>% toupper
names(datakab) %>% t
Format penulisan nama-nama variabel di atas akan mempersulit penulisan program selanjutnya. Fungsi clean_names
dari package janitor
bisa merubah sekaligus seluruh nama variabel dalam data agar mengikuti gaya penulisan nama variabel yang banyak disarankan.
datakab = janitor::clean_names(datakab)
names(datakab) %>% t
Kita bisa sederhanakan lagi nama-nama variabel tahun dengan hanya mengambil karakter setelah garis bawah ( _ ). Kita gunakan fungsi str_replace
dari library stringr
untuk mendeteksi pola karakter yang ingin dihapus, yakni diganti dengan karakter kosong (''
)
datakab %<>% rename_at(vars(starts_with('x20')),
funs(stringr::str_replace(., 'x20[0-9][0-9]_', '')))
datakab %>% names %>% t
Menggabungkan data
Untuk keperluan latihan penggabungan, datakab dipecah menjadi dua data dengan variabel berbeda kecuali variabel ID
data1 = datakab %>% select(region_name:series_code, contains('201'))
names(data1) %>% t
data2 = datakab %>% select(-contains('201'))
names(data2) %>% t
Lalu gabungkan dua data tersebut menggunakan merge
dari base R, atau seri fungsi
_join
dari dplyr
. Penggabungan baris berdasar variabel ID dalam argumen by
. Jika ada variabel bernama sama tapi tidak menjadi argumen by
, maka di data baru variabel tersebut akan ditambahi akhiran .x
dan .y
merge(data1, data2, by = c('region_code', 'series_code')) %>% tail(3)
Jika variabel id berbeda nama di kedua data, pasangkan variabel id dari kedua data dengan tanda =
, dengan format
by = c("ID1_data1" = "ID1_data2", "ID2_data1" = "ID2_data2")
Jika tidak ada argumen by
, penggabungan dilakukan dengan semua variabel bernama sama
dplyr::inner_join(data1, data2) %>% tail(3)
Secara default, hasil merge hanya mempertahankan baris dengan ID yang terdapat di kedua data yang digabungkan. Hasil default merge ini ekuivalen dengan hasil dari dplyr::inner_join
Jika ingin semua baris dipertahankan walau ID hanya terdapat di salah satu data, maka gunakan argumen all = TRUE
. Ini ekuivalen dengan hasil dari dplyr::all_join
Jika hanya ingin mempertahankan semua baris dari salah satu data
- data I gunakan
all.x = TRUE
, ekuivalen dengandplyr::left_join
- data II gunakan
all.y = TRUE
, ekuivalen dengandplyr::right_join
Merubah Nilai
Data dalam tabel bisa dirubah dengan meng-assign nilai baru ke lokasi baris dan kolom yang ingin dirubah. Dimensi nilai yang di-assign harus sama dengan dimensi data yang dirubah. Berikut ini data di baris kedua dan kolom kelima datakab
diganti dari karakter “..” menjadi NA
NA
, kependekan dari Not Available, adalah cara R mengeksplisitkan bagian data yang tidak memiliki nilai (missing values). Sel yang tampak kosong di R adalah karakter kosong yang dianggap ada datanya, yakni observasi yang valid.
datakab[2,5]
(datakab[2,5] = NA)
Di bawah ini bisa dilihat bahwa variabel-variabel tahun didominasi dengan karakter “..” yang sebenarnya mewakili missing values. Karena di atas kita telah mengganti satu observasi menjadi NA
dalam kolom ke-5 data, yakni variabel yr2000
, maka variabel tersebut tidak lagi valid 100%.
dfSummary
dari packagesummarytools
menampilkan ringkasan karakteristik data. Argumengraph.col = F
digunakan karena informasi pada histogram sudah diwakili oleh kolom frekuensiFreqs
. Demikian pulana.col
yang mengandung jumlah dan persentase missing values adalah kebalikan dari kolomValid
.
datakab %>% select(yr2000, yr2001) %>%
summarytools::dfSummary(graph.col = F, na.col = F) %>%
print
Salah satu unsur penyiapan data untuk analisis adalah mengeksplisitkan seluruh missing values pada data menjadi NA
agar diproses secara benar dalam analisis berikutnya. Untuk keperluan ini, kombinasi dplyr::mutate
dan ifelse
bisa digunakan untuk merubah seluruh nilai variabel “..” menjadi NA
.
ifelse
akan memberikan nilai argumen kedua jika ekspresi di argumen pertamanya benar, dan memberikan nilai argumen ketiga jika ekspresi tersebut salah. Uji kesamaan di R menggunakan simbol==
, bukan=
. Ketidaksamaan menggunakan simbol!=
. Sementara relasi lainnya menggunakan simbol matematika seperti umumnya,<
,>
,<=
, dan>=
.
datakab %>% mutate(yr2000 = ifelse(yr2000 == '..', NA, yr2000),
yr2001 = ifelse(yr2001 == '..', NA, yr2001)) %>%
select(yr2000:yr2002) %>%
summarytools::dfSummary(graph.col = F, na.col = F) %>%
print
Gunakan mutate_at
untuk memutasi sekaligus semua variabel yang dipilih dengan fungsi yang sama, tanpa harus mengulang satu per satu. Agar perintah mutasi bisa diterapkan ke semua variabel, nama variabel diganti dengan titik (.
) dalam argumen funs
datakab %<>% mutate_at(vars(starts_with("yr20")), funs(ifelse(. == '..', NA, .)))
Data pada variabel-variabel yang diawali yr
pada dasarnya merupakan variabel angka, sehingga lebih baik dikonversi menjadi tipe angka dengan as.numeric
.
datakab %<>% mutate_at(vars(starts_with("yr20")), as.numeric)
dfSummary
kini dapat menyajikan statitik yang meringkas variabel angka, bukan hanya frekuensi tiap nilai uniknya.
datakab %>% select(starts_with("yr201")) %>%
summarytools::dfSummary(graph.col = F, na.col = F) %>%
print
Pivot Tabel
- Tahun pada dasarnya bukan nama variabel, sehingga bisa dikumpulkan menjadi satu kolom/variabel dengan menggunakan
dplyr::gather
datakab %<>% gather(year, val, starts_with('yr'))
datakab %>% head(2)
Kolom series_code
dan series_name
sebenarnya berisikan nama-nama variabel. Agar data rapi, siap analisis, nama-nama variabel dalam kolom tersebut perlu dijadikan sebagai nama kolom.
dplyr::spread
bisa digunakan untuk keperluan ini. Dalam menerapkannya, salah satu dari series_code
atau series_name
perlu dibuang dulu karena redundan dan justru membuat hasilnya tak sesuai harapan.
datakab %<>% mutate(year = str_replace(year, 'yr', '') %>%
as.integer) %>%
select(-series_code) %>%
spread(key = series_name, value = val)
datakab %>% head(2)
Nama kolom-kolom baru ini tidak memenuhi gaya standar. janitor::clean_names
bisa digunakan lagi untuk menstandarisasi nama. Dan sekedar untuk menyingkat nama variabel, bagian nama yang menjelaskan unit pengukuran bisa dihapus dengan bantuan fungsi str_replace_all
dari library stringr
.
str_replace
danstr_detect
mencari urutan karakter yang memenuhi pola yang dispesifikasi menggunakan syntax regular expression.
datakab %<>% janitor::clean_names()
names(datakab) %<>% str_replace_all('_in_.+$', '') %>% t
datakab %>% names %>% t
Menyimpan dan Menghapus Objek
- simpan semua objek R di memori ke file dengan perintah
save.image
- gunakan
save
jika hanya sebagian objek yang ingin disimpan - simpan image dengan nama
.RData
jika ingin otomatis dimuat ke memori tiap awal menjalankan R dari direktori tersebut
save.image(file = ".RData")
save(datakab, file = "datakab.rda")
- hapus objek R dari memori dengan
rm
rm(data1, data2)
ls()
ls
memberikan vektor nama semua objek yang ada di memori
rm(list = ls())
ls()
-
gunakan
load
untuk memuat semua objek dalam file image ke memori - saat dimuat kembali dari file image, nama objek akan sama dengan saat disimpan
- untuk bisa bebas memberikan nama baru pada objek saat dimuat kembali, simpan dengan
saveRDS
dan muat denganreadRDS
- kedua perintah ini hanya bisa menyimpan dan memuat satu objek
load('datakab.rda')
ls()
saveRDS(datakab, file = "datakab.rds")
indodapoer = readRDS('datakab.rds')
ls()