Hampir setiap pekerjaan analisis data di R melibatkan pengambilan subset, yaitu memilih sebagian elemen dari suatu struktur data. Satu keluarga notasi digunakan di semua struktur, tetapi penerapannya berbeda antara vektor, matriks, list, data frame, dan tibble. Topik ini merangkum aturan pengindeksan tersebut, memisahkan notasi yang mengembalikan wadah dari notasi yang mengembalikan isi, dan menutup dengan perilaku drop pada matriks beserta kesalahan yang paling sering muncul.
Subset pada vektor#
Kurung tunggal [ pada vektor menerima empat jenis indeks, yaitu angka positif, angka negatif, nilai logis, dan nama. Indeks positif memilih posisi yang disebutkan.
nilai <- c(Ali = 80, Budi = 85, Citra = 78, Dewi = 90)
nilai[2]
nilai[c(1, 4)]Budi
85
Ali Dewi
80 90Indeks negatif mengeluarkan posisi yang disebutkan, indeks logis menyaring dengan kondisi, dan indeks berupa nama memilih berdasarkan penamaannya. Contoh berikut menerapkan ketiganya pada vektor yang sama, termasuk kondisi logis yang dibangun dari vektornya sendiri.
nilai[-c(2, 3)]
nilai[nilai >= 80]
nilai["Citra"] Ali Dewi
80 90
Ali Budi Dewi
80 85 90
Citra
78Hasilnya selalu vektor baru, sehingga vektor aslinya tidak berubah. Pola nilai[nilai >= 80] inilah yang menjadi dasar penyaringan baris pada data frame.
Wadah atau isi#
Kaidah pembeda pada struktur berlapis adalah sebagai berikut. Kurung tunggal [ selalu mengembalikan wadah yang sama jenisnya, sedangkan [[ dan $ mengeluarkan isi elemennya. Perbedaannya terlihat dari kelas hasilnya pada list dan data frame.
l <- list(nama = "Ali", nilai = c(80, 85))
class(l["nilai"])
class(l[["nilai"]])[1] "list"
[1] "numeric"siswa <- data.frame(nama = c("Ali", "Budi"), nilai = c(80, 85))
class(siswa["nilai"])
class(siswa[["nilai"]])
class(siswa$nilai)[1] "data.frame"
[1] "numeric"
[1] "numeric"Pada list, l["nilai"] menghasilkan list sepanjang satu, sedangkan l[["nilai"]] menghasilkan vektornya. Pola yang sama berlaku pada data frame, yaitu siswa["nilai"] menghasilkan data frame satu kolom, sedangkan [[ dan $ menghasilkan vektor kolomnya. Karena itu, [[ dan $ umum dipilih apabila isinya akan langsung dihitung, dan [ dipilih apabila bentuk wadahnya perlu dipertahankan. Sebagai tambahan, $ hanya menerima nama, sedangkan [[ menerima nama maupun posisi.
Subset pada matriks dan perilaku drop#
Matriks menerima dua indeks dengan bentuk [baris, kolom]. Perilaku khusus muncul apabila hasilnya tinggal satu baris atau satu kolom, yaitu hasilnya otomatis dilepas dari wadahnya dan berubah menjadi vektor. Perilaku ini disebut drop.
m <- matrix(1:6, nrow = 3)
m[, 1]
class(m[, 1])
m[, 1, drop = FALSE]
class(m[, 1, drop = FALSE])[1] 1 2 3
[1] "integer"
[,1]
[1,] 1
[2,] 2
[3,] 3
[1] "matrix" "array"Argumen drop = FALSE mempertahankan bentuk matriksnya. Perilaku ini penting apabila kolom tunggal akan diteruskan ke fungsi yang mengharapkan matriks, misalnya saat pengindeksan dilakukan di dalam perulangan. Perlu dicatat bahwa drop hanya terjadi pada hasil seleksi satu baris atau satu kolom, tidak pada hasil berukuran lain.
Subset pada data frame dan tibble#
Data frame dan tibble menerima dua indeks dengan bentuk [baris, kolom]. Apabila indeks baris dikosongkan, seluruh baris dipilih, dan apabila indeks kolom dikosongkan, seluruh kolom dipilih. Contoh berikut menggunakan tibble dari tidyverse.
library(tidyverse)
siswa_tbl <- tibble(
nama = c("Ali", "Budi", "Citra", "Dewi"),
nilai = c(80, 85, 78, 90)
)
siswa_tbl── 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: 4 × 2
nama nilai
<chr> <dbl>
1 Ali 80
2 Budi 85
3 Citra 78
4 Dewi 90Indeks baris dan kolom dapat berupa angka maupun nama, dan hasilnya selalu berupa tibble, termasuk apabila kolom yang dipilih hanya satu.
siswa_tbl[c(2, 4), ]
siswa_tbl[, "nilai"]# A tibble: 2 × 2
nama nilai
<chr> <dbl>
1 Budi 85
2 Dewi 90
# A tibble: 4 × 1
nilai
<dbl>
1 80
2 85
3 78
4 90Apabila yang dibutuhkan adalah isinya, gunakan [[ atau $, dan keduanya mengembalikan vektor kolom.
siswa_tbl[["nilai"]]
siswa_tbl$nilai[1] 80 85 78 90
[1] 80 85 78 90Perbedaan [ versus [[ pada tibble lebih tegas daripada pada data frame klasik karena tibble tidak pernah melepas bentuk wadahnya. Prinsip [ mengembalikan wadah dan [[ serta $ mengembalikan isi berlaku konsisten di sini.
Kesalahan umum#
Kesalahan pertama adalah memakai $ pada vektor biasa. Operator $ hanya sah untuk objek berlapis seperti list dan data frame, sehingga vektor atomik (atomic vector) langsung menolaknya dengan error.
v <- c(80, 85)
v$nilaiError in v$nilai : $ operator is invalid for atomic vectorsPesan $ operator is invalid for atomic vectors berarti objek di sebelah kiri $ bukan list maupun data frame. Kesalahan ini sering muncul apabila objek yang dikira data frame ternyata berupa vektor hasil pengindeksan matriks yang sudah mengalami drop.
Kesalahan kedua adalah mengandalkan pencocokan parsial pada $. Operator $ mencocokkan awalan nama secara diam-diam, sehingga l2$nil berhasil mengembalikan elemen nilai_akhir. Apabila awalannya cocok dengan lebih dari satu elemen, hasilnya NULL.
l2 <- list(nilai_akhir = 85, nama = "Dewi")
l2$nil
l2$n[1] 85
NULLRingkasan#
- Kurung tunggal
[menerima indeks positif, negatif, logis, dan nama pada vektor, dan hasilnya selalu vektor baru. [mengembalikan wadah yang sama jenisnya, sedangkan[[dan$mengembalikan isi elemen.- Satu baris atau satu kolom matriks otomatis menjadi vektor karena drop, dan
drop = FALSEmempertahankan bentuk matriksnya. - Pada data frame dan tibble,
[baris, kolom]mengembalikan tabel, sedangkan[[dan$mengembalikan vektor kolom. $menolak vektor atomik dengan error dan melakukan pencocokan parsial yang berisiko, sehingga[[dengan nama lengkap lebih aman dalam skrip.
Referensi#
- An Introduction to R — CRAN — bagian Index vectors menjelaskan jenis indeks dan pengambilan subset.
- R for Data Science, edisi ke-2 — Wickham, Çetinkaya-Rundel, Grolemund — membahas detail pengindeksan vektor, list, dan tibble.