Menu

Filter dan subset data di R (subset, [ ], filter dplyr)

Semua cara untuk mempertahankan baris dan kolom yang kamu inginkan: mask logika dengan kurung siku, subset() dalam satu baris, %in%, jebakan NA, serta filter() dan select() dari dplyr.

Halaman ini dilengkapi editor yang bisa dijalankan. Edit, jalankan, dan lihat output-nya seketika.

Menyaring baris: mask logika

Untuk menyaring data frame di R, taruh kondisi di posisi baris dalam kurung siku: df[condition, ]. Kondisinya dievaluasi menjadi vector TRUE/FALSE, satu untuk setiap baris, dan R mempertahankan baris yang TRUE:

Baca scores[scores$score > 80, ] dari dalam ke luar: scores$score > 80 menghasilkan TRUE FALSE TRUE TRUE FALSE, dan kurung siku mempertahankan baris 1, 3, dan 4. Koma di akhir itu tidak opsional. Kurung siku pada data frame menerima [rows, columns]; mengosongkan slot kolom berarti "semua kolom". Lupakan komanya, maka kamu justru mengindeks kolom, salah satu kesalahan pemula yang paling umum di R.

Perhatikan bahwa nomor baris yang tercetak adalah 1 3 4, bukan 1 2 3: penyaringan mempertahankan label baris aslinya. Tidak berbahaya, tapi sering mengejutkan orang.

Banyak kondisi: & dan | (bukan &&)

Gabungkan kondisi dengan & (AND) dan | (OR). Setiap kondisi mendapat perbandingan lengkapnya sendiri:

Jebakannya: R juga punya && dan ||, dan keduanya tidak bisa saling menggantikan dengan & dan | di sini. Bentuk ganda bekerja pada nilai tunggal (keduanya ada untuk kondisi if); kalau diberi kolom utuh, R modern (4.3+) berhenti dengan error seperti 'length = 5' in coercion to 'logical(1)', dan R versi lama diam-diam hanya membandingkan baris pertama, yang bisa dibilang lebih buruk. Di dalam kurung siku, selalu pakai & dan | tunggal. Dokumentasi operator membahas perbedaannya secara lengkap.

%in%: mencocokkan dengan sekumpulan nilai

Saat sebuah kolom harus cocok dengan salah satu dari beberapa nilai, jangan merangkai == dengan |; pakai %in%:

x %in% set mengembalikan TRUE di mana pun x adalah salah satu nilai di set. Ini lebih enak dibaca daripada status == "pending" | status == "shipped", bisa dipakai untuk berapa pun jumlah nilainya, dan mudah dinegasikan: !(orders$status %in% c("refunded")).

Memilih kolom

Slot kolom dalam kurung siku menerima nama atau posisi:

Dua catatan. Memilih berdasarkan nama tetap aman saat urutan kolom berubah; memilih berdasarkan posisi (scores[, c(1, 3)]) rusak begitu seseorang menyisipkan kolom. Dan meminta satu kolom saja mengembalikan vector biasa, bukan data frame; itulah sebabnya print() kedua menampilkan 91 88 tanpa tabel di sekelilingnya. Saat kamu perlu mempertahankan bentuk data frame, tambahkan drop = FALSE: scores[, "score", drop = FALSE].

subset(): satu baris yang ramah dari base R

Base R menyediakan pembungkus yang menangani baris dan kolom dalam satu pemanggilan yang mudah dibaca, tanpa $ dan tanpa repot mengurus koma:

Di dalam subset() kamu menulis nama kolom apa adanya (score, bukan scores$score); fungsi ini mengevaluasinya terhadap data frame. Ini disebut non-standard evaluation, dan ada peringatan yang terdokumentasi: nama-nama itu diresolusi saat runtime dengan cara yang bisa berperilaku salah di dalam fungsimu sendiri (variabel bernama score di fungsimu bisa tertutupi oleh kolom bernama score). Aturan praktisnya, langsung dari ?subset: bagus untuk penggunaan interaktif, hindari dalam pemrograman, dan pakai pengindeksan kurung siku di sana.

Jebakan NA

Perbandingan dengan NA menghasilkan NA, bukan FALSE, dan penyaringan dengan kurung siku mempertahankan baris dengan mask NA sebagai baris yang penuh NA:

Hasil pertama berisi baris sampah berisi NA karena kondisi baris 2 bukan TRUE dan bukan FALSE. Solusinya adalah mewajibkan !is.na() secara eksplisit. subset() dan filter() dari dplyr sama-sama membuang baris dengan kondisi NA secara diam-diam; praktis, tapi ketahuilah bahwa itu sedang terjadi. Dokumentasi nilai yang hilang membahas mengapa NA menyebar seperti ini.

Cara dplyr: filter() dan select()

Package dplyr membagi tugasnya menjadi dua verb, filter() untuk baris dan select() untuk kolom, dengan nama kolom apa adanya dan tanpa pengulangan df$ (statis; sandbox ini hanya menjalankan base R):

library(dplyr)

scores |> filter(score > 80)
scores |> filter(score > 80, team == "red")     # comma = AND
scores |> filter(status %in% c("pending", "shipped"))
scores |> select(name, score)
scores |> filter(team == "red") |> select(name, score)

filter() otomatis membuang baris dengan kondisi NA dan selalu mengembalikan data frame (tidak pernah vector biasa), sehingga kedua jebakan base R di atas hilang. Gantinya adalah dependensi package dan peringatan non-standard evaluation yang sama seperti subset(); lihat pengantar dplyr untuk tur lengkap verb-nya.

Yang kamu bawa pulang

  • df[condition, ] adalah idiom dasarnya, dan komanya wajib.
  • Gabungkan kondisi dengan & dan | tunggal; && memunculkan error pada vector.
  • %in% lebih baik daripada == yang dirangkai untuk mencocokkan sekumpulan nilai.
  • Pilih kolom berdasarkan nama, dan ingat bahwa satu kolom saja turun menjadi vector kecuali drop = FALSE.
  • subset() adalah satu baris yang nyaman untuk penggunaan interaktif; kurung siku adalah pilihan untuk pemrograman.
  • Perbandingan dengan NA menghasilkan baris hantu dalam kurung siku; lindungi dengan !is.na().

Berikutnya: menambah dan mengubah kolom dengan df$new <- ..., ifelse(), dan mutate() dari dplyr.

Pertanyaan yang sering diajukan

Bagaimana cara menyaring baris data frame di R?

Taruh kondisi logika di posisi baris dalam kurung siku: df[df$score > 80, ]. Kondisinya menghasilkan vector TRUE/FALSE, dan R mempertahankan baris yang TRUE. Komanya penting: koma memisahkan filter baris dari filter kolom (yang kosong). subset(df, score > 80) melakukan hal yang sama dengan ketikan lebih sedikit.

Bagaimana cara menyaring dengan banyak kondisi di R?

Gabungkan kondisi dengan & (AND) dan | (OR): df[df$score > 80 & df$team == "red", ]. Pakai & tunggal, bukan &&: bentuk ganda hanya bekerja pada nilai tunggal dan memunculkan error pada vector di R modern.

Apa perbedaan subset() dan menyaring dengan kurung siku di R?

Keduanya mempertahankan baris yang sama, dengan dua perbedaan: subset() diam-diam membuang baris yang kondisinya NA (kurung siku mempertahankannya sebagai baris berisi NA), dan subset() memakai non-standard evaluation. Kamu menulis nama kolom apa adanya, yang praktis saat interaktif tapi tidak bisa diandalkan di dalam fungsimu sendiri.

Bagaimana cara menyaring baris yang kolomnya cocok dengan daftar nilai?

Pakai %in%: df[df$team %in% c("red", "blue"), ] mempertahankan baris yang team-nya salah satu dari nilai yang didaftar. Operator ini menggantikan rangkaian perbandingan == yang disambung dengan |, dan tidak seperti ==, operator ini tidak pernah mengembalikan NA.

Ilustrasi bahasa pemrograman di Coddy

Belajar coding dengan Coddy

Mulai