List menampung apa saja
Vector punya satu aturan keras: setiap elemen harus bertipe sama. List tidak punya aturan itu. Setiap elemen list bisa punya tipe yang berbeda, panjang yang berbeda, bahkan berupa list lain. Inilah wadah serbaguna di R:
length() melaporkan 4, yaitu empat elemen, meskipun salah satunya (scores) sendiri berisi tiga angka. List menghitung kompartemennya, bukan isinya. str() (structure) adalah cara tercepat untuk melihat apa sebenarnya isi sebuah list: satu baris per elemen dengan nama, tipe, dan pratinjaunya. Jadikan str() refleks: setiap kali sebuah fungsi memberimu sesuatu dan kamu tidak yakin itu apa, jalankan str() padanya.
Nama itu opsional (list(1, "a", TRUE) sah), tapi hampir selalu layak dipakai: named list menjelaskan dirinya sendiri.
Tiga cara masuk: [, [[, dan $
Inilah bagian list yang pernah salah dipahami semua orang setidaknya sekali, jadi mari kita pahami dengan tepat. Ada tiga operator akses, dan ketiganya melakukan dua pekerjaan yang berbeda:
[mengembalikan list yang lebih kecil, wadah dari jenis yang sama, berisi apa pun yang kamu pilih.[[mengembalikan elemennya sendiri, nilai sebenarnya di dalam kompartemen itu.$adalah singkatan untuk[[dengan nama harfiah:person$agesama denganperson[["age"]].
Perbedaannya tidak terlihat saat kamu mencetak sekilas, tapi sangat terlihat begitu kamu mencoba menghitung:
person["scores"] punya class "list", yaitu list sepanjang 1 dengan vector skor di dalamnya. person[["scores"]] punya class "numeric", yaitu vector itu sendiri, siap untuk mean(). Panggil mean() pada versi kurung siku tunggal dan kamu mendapat error bahwa argumennya bukan numerik; pesan error itu hampir selalu menandakan kamu memakai [ padahal maksudmu [[.
Perumpamaan yang mudah diingat: list adalah sebuah kereta. [ memberimu kereta yang lebih pendek, tapi tetap kereta. [[ membuka satu gerbong dan menyerahkan muatannya.
Jadi kapan [ adalah alat yang tepat? Saat kamu menginginkan beberapa elemen dan ingin tetap mengemasnya:
Kamu tidak bisa mengambil dua elemen "itu sendiri" sekaligus (dua nilai butuh wadah), jadi pemilihan banyak elemen selalu memakai kurung siku tunggal, dan selalu menghasilkan list.
Satu perbedaan lagi: $ memakai pencocokan parsial (person$sc menemukan scores kalau tidak ambigu), yang praktis di console tapi menjadi beban di skrip. Di kode yang harus terus berjalan, utamakan [[ dengan nama lengkap; cara ini juga menerima nama yang disimpan di variabel, hal yang tidak bisa dilakukan $.
Menambah, mengubah, menghapus
List bertambah dan berkurang dengan penugasan biasa, tanpa perlu method append khusus:
- Mengisi ke nama yang belum ada menambahkan elemen.
- Mengisi ke nama yang sudah ada mengganti elemennya.
- Mengisi ke posisi
length(x) + 1menambahkan elemen tanpa nama di akhir. - Mengisi dengan
NULLmenghapus elemen sepenuhnya, sehingga list-nya jadi lebih pendek. (Inilah satu-satunya tempatNULLberfungsi sebagai perintah hapus; kalau kamu benar-benar perlu menyimpan "kosong" di sebuah kompartemen, pakaix["k"] <- list(NULL).)
Untuk menyambung dua list, c() bekerja pada list sama seperti pada vector: c(list_a, list_b) mengembalikan satu list yang lebih panjang.
List bersarang
Karena elemen list bisa berupa list lain, list bisa bersarang sedalam apa pun, sehingga menjadi bentuk alami R untuk data terstruktur seperti JSON yang sudah diurai atau hasil yang dikelompokkan:
Menelusuri ke dalam cukup dengan merangkai operator akses: setiap $ atau [[ melangkah satu tingkat lebih dalam. Saat struktur bersarang mulai membingungkan, str(company) menampilkan seluruh pohonnya sekaligus, dan str(company, max.level = 1) hanya menampilkan lapisan teratasnya.
Meratakan dengan unlist()
unlist() meruntuhkan sebuah list, sedalam apa pun sarangnya, menjadi satu vector:
Ada dua hal yang perlu diperhatikan. Pertama, unlist() membuatkan nama untukmu (math1, math2, art) sehingga kamu masih bisa tahu dari mana setiap nilai berasal. Kedua, dan inilah jebakannya, vector hanya menampung satu tipe, jadi meratakan list yang bercampur memaksa semuanya ke tipe paling fleksibel yang ada. Angka 1 kembali sebagai string "1". Kalau kamu melakukan unlist dan angka-angkamu berubah menjadi teks, berarti list-nya tidak seseragam yang kamu kira.
Mengapa list penting
List bisa terasa seperti topik pemula yang nanti akan kamu tinggalkan. Kenyataannya justru sebaliknya: list menopang seluruh bahasa ini:
- Fungsi yang mengembalikan beberapa hal mengembalikan list. Fungsi R mengembalikan satu objek; list membuat satu objek itu bisa membawa nilai hasil model di sini, tabel koefisien di sana. Saat kamu menjalankan regresi, objek model yang kamu terima adalah list (besar dan punya class);
str()pada objek itu membuktikannya. - Data frame adalah list berisi kolom, yaitu vector yang sama panjang dengan sedikit perilaku tambahan di atasnya. Semua yang baru saja kamu pelajari (
$,[[, mengisiNULLuntuk membuang elemen) berlaku persis pada kolom data frame. - Keluarga apply (
lapply()dan kawan-kawannya) menerima list, menerapkan sebuah fungsi pada setiap elemen, lalu mengembalikan list. List masuk, list keluar: itulah bentuk standar perhitungan berulang di R.
Yang kamu bawa pulang
- List menampung apa saja: tipe campuran, panjang yang tidak sama, list lain, hingga data frame utuh.
[mengembalikan list yang lebih kecil;[[mengembalikan elemennya sendiri;$adalah[[dengan nama harfiah. Mau menghitung? Kamu butuh[[atau$.- Tambah dengan mengisi ke nama baru, hapus dengan mengisi
NULL, gabungkan denganc(). unlist()meratakan menjadi vector dan memaksa tipe yang bercampur dalam prosesnya; periksa class hasilnya.- Data frame adalah list berisi kolom, jadi pengetahuan ini langsung berlaku di sana.
Berikutnya: matrix, pasangan list yang semuanya satu tipe dan tersusun dalam baris dan kolom.
Pertanyaan yang sering diajukan
Apa perbedaan [ dan [[ di R?
Kurung siku tunggal [ selalu mengembalikan list berisi elemen yang dipilih, yaitu wadah yang lebih kecil dari jenis yang sama. Kurung siku ganda [[ masuk ke dalam dan mengembalikan elemennya sendiri. Kalau x$scores berisi numeric vector, x["scores"] adalah list sepanjang 1 dan x[["scores"]] adalah numeric vector itu. Pakai [[ (atau $) saat kamu benar-benar ingin bekerja dengan nilainya.
Bagaimana cara menambahkan elemen ke list di R?
Isi ke nama yang belum ada: x$email <- "rosa@example.com" atau x[["email"]] <- .... List-nya bertambah secara otomatis. Untuk menambahkan tanpa nama, isi ke posisi berikutnya: x[[length(x) + 1]] <- value. Untuk menghapus elemen, isi dengan NULL: x$email <- NULL.
Bagaimana cara mengubah list menjadi vector di R?
unlist(x) meratakan sebuah list (termasuk yang bersarang) menjadi satu vector. Karena vector hanya menampung satu tipe, semuanya dipaksa ke tipe paling fleksibel yang ada: list berisi angka dan string menjadi vector yang seluruhnya character. Periksa class() hasilnya setelah unlist.