Masalah yang Diselesaikan Pipe
Pipe mengambil nilai di depannya dan memberikannya ke panggilan fungsi sesudahnya: x |> f() berarti f(x). Kedengarannya seperti penulisan ulang yang sepele, sampai kamu merangkai tiga atau empat langkah. Tanpa pipe, transformasi bertahap jadi bersarang, dan panggilan bersarang dibaca terbalik: hal yang terjadi pertama justru ada di posisi paling dalam.
Untuk membaca round(sqrt(x), 1), kamu mulai dari tengah (x), bergerak ke luar (sqrt, lalu round), dan harus mengingat , 1) di belakang itu milik panggilan yang mana. Dengan tiga tingkat ini sudah menjengkelkan; dengan lima tingkat, berisi kata kerja data frame yang masing-masing punya beberapa argumen, kodenya benar-benar sulit diikuti. Alternatif yang biasa dipakai orang, yaitu menyimpan setiap langkah antara ke tmp1, tmp2, tmp3, memenuhi workspace dengan nama yang tidak dibutuhkan siapa pun.
Pipe menulis ulang rangkaian itu sesuai urutan langkah yang sebenarnya terjadi: ambil x, lalu hitung akar kuadratnya, lalu bulatkan.
Pipe Bawaan |>
Sejak R 4.1, pipe sudah menjadi bagian dari bahasa itu sendiri, tanpa perlu package. |> menyisipkan nilai sebelumnya sebagai argumen pertama dari panggilan berikutnya:
c(1, 4, 9, 16) |> sqrt() |> round(1) sama persis dengan round(sqrt(c(1, 4, 9, 16)), 1). R benar-benar menulis ulang yang satu menjadi yang lain saat parsing, jadi tidak ada biaya tambahan sama sekali saat berjalan. Tetapi sekarang kodenya terbaca seperti resep, dari atas ke bawah: datanya, lalu setiap transformasi secara berurutan. Ini bekerja dengan fungsi apa pun, bukan hanya alat data: mtcars |> head(3) sepenuhnya R dasar.
Perhatikan betapa cocoknya pipe dengan fungsi yang parameter pertamanya adalah "data": head, sort, unique, summary, dan semua kata kerja dplyr memang dirancang seperti itu, itulah sebabnya pipeline terasa begitu alami di R.
Aturan |>
Pipe bawaan sengaja dibuat ketat. Tiga aturan mencakup hampir semuanya:
1. Langkah berikutnya harus berupa panggilan, dengan tanda kurung. x |> sqrt adalah error sintaks; kamu harus menulis x |> sqrt():
c(1, 4, 9) |> sqrt # Error: The pipe operator requires a function call as RHS
c(1, 4, 9) |> sqrt() # correct
2. Nilainya mendarat di posisi argumen pertama. Argumen tambahan yang kamu tulis tetap di tempatnya, sesudah nilai itu: x |> round(1) adalah round(x, 1).
3. Untuk mendarat di tempat lain, pakai placeholder _ dengan argumen bernama (R 4.2+). Kasus klasiknya: lm menerima formula lebih dulu dan data sesudahnya, jadi menyalurkan data frame ke dalamnya butuh data = _:
_ hanya boleh muncul sekali, dan hanya sebagai argumen bernama. Kalau itu terlalu membatasi, salurkan ke fungsi anonim, yang bisa menaruh nilainya di mana saja:
Lambda itu dibungkus tanda kurung lalu dipanggil dengan (), sehingga aturan 1 tetap terpenuhi. Kalau kamu sering melakukan ini dalam satu pipeline, langkah itu mungkin lebih baik dijadikan fungsi bernama.
Pipe magrittr %>%
Sebelum bahasanya punya pipe, package magrittr menyediakannya, dan %>% menjadi ciri khas kode tidyverse: memuat dplyr otomatis memberimu operator ini. Kamu akan melihatnya di hampir setiap tutorial dan script dplyr yang ditulis dalam satu dekade terakhir:
library(dplyr)
mtcars %>%
filter(mpg > 30) %>%
select(mpg, wt)
Karena %>% berasal dari sebuah package, contoh-contoh ini tidak bisa dijalankan di sesi R kosong: Error: could not find function "%>%" persis itulah yang kamu dapat kalau lupa library(dplyr) (atau library(magrittr)).
Untuk kasus umum, perilakunya sama dengan |>: memberikan nilai sebelumnya ke argumen pertama panggilan berikutnya. Tetapi magrittr lebih longgar:
c(1, 4, 9) %>% sqrt # bare function name - no parentheses needed
mtcars %>% lm(mpg ~ wt, data = .) # . placeholder, usable anywhere
c(-2, 3) %>% { max(abs(.)) } # . can even appear several times, in nested calls
|> vs %>%: Perbedaan yang Penting
Untuk pipeline argumen pertama, yang merupakan sebagian besar kode sungguhan, keduanya bisa saling menggantikan. Perbedaannya ada di pinggiran:
- Ketersediaan:
|>adalah R dasar 4.1+;%>%butuh magrittr (biasanya lewat dplyr). - Tanda kurung:
|>mewajibkansqrt();%>%menerimasqrtpolos. - Placeholder:
|>memakai_, sekali, hanya sebagai argumen bernama (4.2+);%>%memakai., di mana saja, berapa kali pun, termasuk di dalam panggilan bersarang. - Kecepatan:
|>ditulis ulang saat parsing menjadi panggilan bersarang, tanpa biaya.%>%adalah panggilan fungsi biasa dengan sedikit overhead (yang dalam praktik bisa diabaikan).
Tidak ada di sini yang membuat %>% salah: operator ini sudah teruji dan sedikit lebih fleksibel. Tetapi semua yang ia lakukan di luar kemampuan |> bisa dikerjakan dengan lambda, dan pipe dasar tidak butuh dependensi.
Mana yang Sebaiknya Kamu Pakai?
Untuk kode baru: pakai |>. Ia bagian dari bahasa, bekerja di mana pun R 4.1+ berjalan, tidak butuh package, dan keketatannya justru menjadi keunggulan: pipeline tetap sederhana atau di-refactor menjadi fungsi bernama.
Tetapi kamu harus bisa membaca %>% dengan lancar, karena codebase tidyverse, jawaban di Stack Overflow, dan sebagian besar buku R yang ditulis sejak 2014 penuh dengan operator itu. Tim yang sudah punya gaya dplyr sering tetap memakai %>% demi konsistensi, dan itu keputusan yang masuk akal; pilihan terburuk adalah mencampur kedua operator dalam satu file. Apa pun yang kamu tulis, ada satu kebiasaan yang berlaku untuk keduanya: di pipeline yang panjang, taruh setiap langkah di barisnya sendiri dengan pipe di akhir baris, supaya resepnya terbaca sebagai daftar langkah.
Selera yang sama berlaku seperti pada keluarga apply: pipe cocok untuk transformasi linear, langkah demi langkah. Ketika sebuah perhitungan bercabang atau butuh hasil antara dua kali, simpan ke variabel dengan nama yang baik alih-alih memaksa semuanya lewat satu rangkaian.
Yang Perlu Kamu Ingat
- Pipe memberikan nilai sebelumnya ke panggilan berikutnya:
x |> f() |> g()adalahg(f(x)), ditulis sesuai urutan kejadiannya. |>adalah R dasar (4.1+): wajib tanda kurung, menyasar argumen pertama, placeholder_dengan argumen bernama (4.2+).%>%adalah magrittr/tidyverse: nama polos boleh, placeholder.di mana saja, tetapi butuh package.- Utamakan
|>di kode baru; baca%>%di tempat lain tanpa ragu. - Pipe cocok untuk resep linear; logika yang bercabang layak diberi variabel bernama.
Berikutnya: package, asal sebenarnya %>%, dplyr, dan 20.000 ekstensi R lainnya.
Pertanyaan yang sering diajukan
Apa arti %>% di R?
%>% adalah pipe magrittr: ia mengambil nilai di depannya dan memberikannya sebagai argumen pertama dari panggilan sesudahnya, jadi x %>% f() %>% g() berarti g(f(x)). Operator ini berasal dari package magrittr dan dimuat otomatis bersama dplyr dan tidyverse; ia bukan bagian dari R dasar.
Apakah aku butuh package untuk memakai |> di R?
Tidak. |> adalah pipe bawaan, yang sudah ada di R dasar sejak versi 4.1, dan bekerja di sesi R biasa tanpa menginstal apa pun. Yang butuh package adalah %>% (magrittr, atau package apa pun yang mengekspornya ulang, seperti dplyr).
Apa bedanya |> dan %>% di R?
Keduanya memberikan nilai sebelumnya ke panggilan berikutnya. |> adalah R dasar, wajib memakai tanda kurung (x |> sqrt()), dan memakai placeholder _ hanya dengan argumen bernama. %>% butuh magrittr, menerima nama fungsi polos (x %>% sqrt), dan placeholder . miliknya bisa ditaruh di mana saja, berapa kali pun. Untuk kasus umum argumen pertama, perilakunya sama persis.