Mendefinisikan dan memanggil fungsi
Fungsi di R adalah sebuah nilai, seperti angka atau string. Kamu membuatnya dengan kata kunci function dan menempelkannya ke sebuah nama dengan <-, sama seperti saat menyimpan apa pun ke dalam variabel:
Bagian-bagiannya: function(x) mendeklarasikan satu parameter bernama x, kurung kurawal berisi isi fungsinya, dan memanggil square(4) menjalankan isinya dengan x bernilai 4. Untuk isi satu baris, kurung kurawal boleh dihilangkan (square <- function(x) x^2 adalah fungsi yang sama), tapi kurung kurawal lebih enak dibaca begitu isinya bertambah panjang.
Karena fungsi hanyalah sebuah nilai, semua yang kamu ketahui tentang variabel tetap berlaku: kamu bisa menugaskannya ulang, memberikannya ke fungsi lain, atau menyimpannya di list. Satu fakta itu menggerakkan separuh R yang idiomatis, termasuk seluruh keluarga apply.
Nilai kembalian: ekspresi terakhir yang menang
Fungsi R mengembalikan apa pun yang dihasilkan ekspresi terakhir yang dievaluasinya. Tidak ada pernyataan return yang wajib:
return() memang ada, dan bekerja seperti yang kamu harapkan: fungsi langsung berhenti dan mengembalikan argumennya. R yang idiomatis menyimpannya untuk keluar lebih awal: berhenti di bagian atas saat sebuah input membuat sisa pekerjaannya sia-sia. Pasangkan dengan pemeriksaan if-else:
Menulis return(a / b) di baris terakhir tidak salah, hanya menambah kebisingan. Simpan return() untuk jalan keluar yang terjadi lebih awal, dan biarkan ekspresi terakhir berbicara untuk jalur normalnya.
Nilai default dan argumen bernama
Sebuah parameter bisa punya nilai default, dideklarasikan dengan = di daftar parameter. Pemanggil yang puas dengan default-nya cukup tidak menyertakan argumen itu:
Pemanggilan ketiga menunjukkan separuh cerita lainnya: argumen bernama. Saat kamu menulis name = "Ada" di tempat pemanggilan, posisi tidak lagi penting: R mencocokkan berdasarkan nama lebih dulu, lalu mengisi parameter yang tersisa berdasarkan posisi. Dua aturan praktis muncul dari sini:
- Taruh parameter wajib lebih dulu dan parameter dengan default sesudahnya, supaya pemanggilan berdasarkan posisi tetap terasa alami.
- Di tempat pemanggilan, beri nama pada argumen apa pun yang tidak jelas dari posisinya.
greet("Ada", punctuation = "?")lebih jelas daripada memaksa pembaca menghitung koma.
Meneruskan argumen dengan ...
Parameter khusus ... (disebut "dots" atau titik-titik) berarti "argumen tambahan berapa pun jumlahnya." Fungsi yang mendeklarasikan ... bisa menerima argumen yang tidak pernah didaftarnya dan meneruskannya ke fungsi lain:
shout() tidak tahu dan tidak peduli berapa banyak kata yang kamu berikan; semuanya diteruskan ke paste(). Perhatikan bahwa punctuation berada setelah titik-titik: parameter apa pun yang dideklarasikan setelah ... hanya bisa diatur berdasarkan nama, dan memang itulah yang kamu inginkan untuk opsi. Pola meneruskan argumen ini ada di mana-mana di base R: sapply(x, round, digits = 2) bekerja karena sapply meneruskan digits = 2 ke round lewat ... miliknya sendiri.
Harga yang harus dibayar untuk titik-titik adalah salah ketik bisa lolos diam-diam: salah mengeja punctuation menjadi punctation, maka argumen itu tertelan ke dalam ... alih-alih memunculkan error. Jaga agar fungsi yang memakai titik-titik tetap kecil.
Fungsi anonim
Saat sebuah fungsi hanya dibutuhkan sekali (biasanya sebagai argumen untuk fungsi lain), kamu bisa melewatkan namanya sama sekali:
Kedua baris melakukan hal yang sama. function(x) x^2 adalah cara penulisan klasiknya; \(x) x^2 adalah singkatan yang ditambahkan di R 4.1, dengan \ menggantikan kata function. Keduanya identik dalam segala hal kecuali jumlah ketikan; singkatan itu bukan jenis fungsi yang berbeda.
Pakai fungsi anonim saat operasinya cukup satu baris dan terikat pada satu tempat pemanggilan. Begitu kamu menempelkan lambda yang sama di dua tempat, atau isinya melebihi satu baris, beri nama: fungsi bernama bisa diuji dan menjelaskan dirinya sendiri.
Scoping: apa yang bisa dilihat sebuah fungsi
R memakai lexical scoping: saat sebuah fungsi membutuhkan variabel yang tidak ditemukannya di antara parameter dan penugasan lokalnya sendiri, ia mencari di environment tempat fungsi itu didefinisikan, bukan tempat ia dipanggil. Dalam praktiknya, ini berarti fungsi bisa membaca variabel dari skrip di sekitarnya:
Sisi sebaliknya: penugasan di dalam fungsi tidak pernah bocor keluar. rate <- 0.5 di dalam change_inside membuat variabel lokal baru yang mati saat fungsinya selesai; rate di luar tetap mencetak 0.1. Ini fitur (fungsi tidak bisa tanpa sengaja mengacak-acak workspace-mu), tapi mengejutkan pemula yang mengira penugasan di dalam akan bertahan. Kalau sebuah fungsi perlu menyerahkan hasil ke dunia luar, kembalikan hasilnya dan lakukan penugasan di tempat pemanggilan. (Ada operator <<- yang menjangkau ke luar; anggap itu tanda kode yang bermasalah sampai kamu benar-benar membutuhkannya.)
Contoh lengkap
Inilah pola yang membuahkan hasil: sadari bahwa kamu mengulang tiga baris analisis, bungkus dalam sebuah fungsi, lalu pakai ulang. Misalnya kamu terus meringkas vector berisi hasil pengukuran:
Semua yang ada di halaman ini ada di sana: parameter digits dengan default, pemanggilan bernama yang menimpanya, dan ekspresi terakhir (round(out, digits)) yang melakukan pengembalian. Fungsinya terbaca seperti kalimat, bisa dipakai pada numeric vector apa pun, dan berada di satu tempat saat kamu memutuskan untuk menambahkan median.
Yang kamu bawa pulang
name <- function(args) { body }membuat sebuah fungsi; ekspresi terakhir yang dievaluasi adalah nilai kembaliannya.return()untuk keluar lebih awal, bukan untuk baris terakhir yang normal.- Default dideklarasikan dengan
=di daftar parameter; argumen bernama membuat tempat pemanggilan tidak bergantung pada urutan dan mudah dibaca. ...menerima dan meneruskan argumen tambahan apa pun; kuat, tapi menyembunyikan salah ketik.function(x)dan\(x)adalah hal yang sama; pakai fungsi anonim untuk satu baris sekali pakai.- Fungsi membaca variabel dari tempat ia didefinisikan; penugasan di dalamnya tetap di dalam.
Berikutnya: keluarga apply, fungsi-fungsi yang menerima fungsi buatanmu dan menjalankannya pada seluruh vector dan list.
Pertanyaan yang sering diajukan
Bagaimana cara membuat fungsi di R?
Simpan sebuah objek function ke sebuah nama: square <- function(x) { x^2 }. Parameternya ditaruh di dalam tanda kurung, isinya di dalam kurung kurawal, dan kamu memanggilnya seperti square(4). Ekspresi terakhir yang dievaluasi adalah nilai yang dikembalikan fungsi.
Apakah perlu return() di R?
Tidak. Fungsi R otomatis mengembalikan nilai ekspresi terakhir yang dievaluasinya. return() memang ada, dan R yang idiomatis memakainya untuk keluar lebih awal: berhenti di bagian atas fungsi saat input-nya tidak valid atau saat sebuah kasus khusus sudah ditangani.
Apa itu fungsi anonim di R?
Fungsi yang kamu definisikan tanpa memberinya nama, biasanya langsung diberikan ke fungsi lain: sapply(x, function(v) v^2). Sejak R 4.1 ada juga singkatan \(v) v^2, yang artinya persis sama dengan ketikan lebih sedikit.