Apa perbedaan antara operator penugasan =
dan <-
dalam R?
Saya tahu bahwa operator sedikit berbeda, seperti yang ditunjukkan contoh ini
x <- y <- 5
x = y = 5
x = y <- 5
x <- y = 5
# Error in (x <- y) = 5 : could not find function "<-<-"
Tetapi apakah ini satu-satunya perbedaan?
r
assignment-operator
r-faq
csgillespie
sumber
sumber
<-
simbol berasal dari keyboard APL lama yang sebenarnya memiliki satu<-
kunci saja.Jawaban:
Seperti yang ditunjukkan contoh Anda,
=
dan<-
memiliki prioritas operator yang sedikit berbeda (yang menentukan urutan evaluasi ketika mereka dicampur dalam ekspresi yang sama). Bahkan,?Syntax
dalam R memberikan tabel prioritas operator berikut, dari tertinggi ke terendah:Tetapi apakah ini satu-satunya perbedaan?
Karena Anda bertanya tentang operator penugasan : ya, itulah satu-satunya perbedaan. Namun, Anda akan dimaafkan karena percaya sebaliknya. Bahkan dokumentasi R dari
?assignOps
klaim bahwa ada lebih banyak perbedaan:Jangan terlalu menekankan hal itu: dokumentasi R (secara halus) salah [ 1 ] . Ini mudah ditunjukkan: kita hanya perlu menemukan contoh tandingan dari
=
operator yang tidak (a) di tingkat atas, atau (b) subekspresi dalam daftar ekspresi yang diperkuat (yaitu{…; …}
). - Tanpa basa-basi:Jelas kami telah melakukan tugas, menggunakan
=
, di luar konteks (a) dan (b). Jadi, mengapa dokumentasi fitur bahasa R inti salah selama beberapa dekade?Itu karena dalam sintaks R simbol
=
memiliki dua makna berbeda yang secara rutin digabungkan:=
operator yang tidak melakukan tindakan saat runtime, itu hanya mengubah cara ekspresi diurai.Ayo lihat.
Dalam bentuk kode apa pun dari bentuk umum ...
… The
=
adalah token yang mendefinisikan lewat argumen: itu bukan operator penugasan. Lebih jauh lagi,=
sepenuhnya dilarang dalam beberapa konteks sintaksis:Semua ini akan menimbulkan kesalahan “tak terduga '=' di ‹bla›”.
Dalam konteks lain,
=
merujuk pada panggilan operator penugasan. Secara khusus, hanya menempatkan tanda kurung di sekitar subekspresi membuat salah satu dari yang di atas (a) valid, dan (b) tugas . Misalnya, berikut ini melakukan tugas:Tetapi juga:
Sekarang Anda mungkin keberatan bahwa kode seperti itu mengerikan (dan Anda mungkin benar). Tapi saya mengambil kode ini dari
base::file.copy
fungsi (ganti<-
dengan=
) - ini adalah pola meresap di banyak basis kode R inti.The penjelasan asli oleh John Chambers , yang dokumentasi R yang mungkin didasarkan pada, sebenarnya menjelaskan ini dengan benar:
Sebuah pengakuan: Saya berbohong sebelumnya. Ada adalah satu perbedaan tambahan antara
=
dan<-
operator: mereka memanggil fungsi-fungsi yang berbeda. Secara default fungsi-fungsi ini melakukan hal yang sama tetapi Anda dapat menimpa keduanya secara terpisah untuk mengubah perilaku. Sebaliknya,<-
dan->
(tugas dari kiri ke kanan), meskipun secara sintaksis berbeda, selalu memanggil fungsi yang sama . Mengesampingkan satu juga mengesampingkan yang lain. Mengetahui hal ini jarang praktis tetapi dapat digunakan untuk beberapa shenanigans yang menyenangkan .sumber
?
sebenarnya ada di antara=
dan<-
, yang memiliki konsekuensi penting ketika mengesampingkan?
, dan hampir tidak ada yang sebaliknya.main/gram.y
), prioritas?
didokumentasikan dengan benar, dan lebih rendah dari keduanya=
dan<-
.=
mendapatkan perlakuan khusus sebelum pohon parse dibangun. Mungkin terkait dengan argumen fungsi, masuk akal bahwafoo(x = a ? b)
kita akan mencari=
sebelum menguraikan sisa ekspresi.Perbedaan dalam operator penugasan lebih jelas ketika Anda menggunakannya untuk menetapkan nilai argumen dalam panggilan fungsi. Sebagai contoh:
Dalam hal ini,
x
dinyatakan dalam lingkup fungsi, sehingga tidak ada di ruang kerja pengguna.Dalam hal ini,
x
dideklarasikan di ruang kerja pengguna, sehingga Anda dapat menggunakannya setelah pemanggilan fungsi selesai.Ada preferensi umum di antara komunitas R untuk menggunakan
<-
untuk penugasan (selain dari pada tanda tangan fungsi) untuk kompatibilitas dengan (sangat) versi lama S-Plus. Perhatikan bahwa spasi membantu menjelaskan situasi sepertiSebagian besar R IDE memiliki pintasan keyboard untuk
<-
memudahkan mengetik. Ctrl+ =di Arsitek, Alt+ -di RStudio ( Option+ di -bawah macOS), Shift+ -(garis bawah) di emacs + ESS.Jika Anda lebih suka menulis
=
untuk<-
namun ingin menggunakan simbol tugas yang lebih umum untuk kode dirilis ke publik (di CRAN, misalnya), maka Anda dapat menggunakan salah satutidy_*
fungsi dalamformatR
paket secara otomatis mengganti=
dengan<-
.Jawaban untuk pertanyaan "Mengapa
x <- y = 5
melempar kesalahan tetapi tidakx <- y <- 5
?" adalah "Ini ke sihir yang terkandung dalam parser". Sintaks R berisi banyak kasus ambigu yang harus diselesaikan dengan satu atau lain cara. Parser memilih untuk menyelesaikan bit ekspresi dalam urutan berbeda tergantung pada apakah=
atau<-
tidak digunakan.Untuk memahami apa yang terjadi, Anda perlu tahu bahwa tugas secara diam-diam mengembalikan nilai yang ditugaskan. Anda dapat melihatnya lebih jelas dengan mencetak secara eksplisit, misalnya
print(x <- 2 + 3)
.Kedua, lebih jelas jika kita menggunakan notasi awalan untuk penugasan. Begitu
Parser mengartikan
x <- y <- 5
sebagaiKita mungkin berharap itu
x <- y = 5
akan terjaditetapi sebenarnya itu akan ditafsirkan sebagai
Ini karena
=
lebih diutamakan daripada<-
, seperti yang ditunjukkan pada?Syntax
halaman bantuan.sumber
median((x = 1:10))
memiliki efek yang sama denganmedian(x <- 1:10)
.x <- x = 5
ditafsirkan sedikit salah: Pada kenyataannya, R menafsirkannya sebagai`<-<-`(x, y = 5, value = 5)
(yang itu sendiri kurang lebih setara dengantmp <- x; x <- `<-<-`(tmp, y = 5, value = 5)
). Astaga!=
panggilan fungsi tidak melakukan penugasan , dan bukan operator penugasan. Ini adalah ekspresi R yang diuraikan sepenuhnya berbeda, yang kebetulan menggunakan karakter yang sama. Lebih lanjut, kode yang Anda tunjukkan tidak “menyatakan”x
dalam lingkup fungsi. The deklarasi fungsi Melakukan kata deklarasi. Panggilan fungsi tidak (itu menjadi sedikit lebih rumit dengan...
argumen bernama ).Panduan gaya R Google menyederhanakan masalah dengan melarang "=" untuk penugasan. Bukan pilihan yang buruk.
https://google.github.io/styleguide/Rguide.xml
Manual R menjelaskan secara rinci semua 5 operator penugasan.
http://stat.ethz.ch/R-manual/R-patched/library/base/html/assignOps.html
sumber
x<-y
saatx < -y
itu dimaksudkan, membuat saya sangat kesal yang secara pribadi saya sukai=
. Memiliki kode Anda bergantung pada spasi yang ada tampaknya tidak baik bagi saya. Tidak masalah untuk menyarankan spasi sebagai saran gaya tetapi untuk kode Anda berjalan berbeda apakah ada ruang di sana atau tidak? Bagaimana jika Anda memformat ulang kode Anda, atau menggunakan pencarian dan ganti, spasi putih kadang-kadang bisa hilang dan kode menjadi serba salah. Itu tidak masalah=
. IIUC, melarang=
sama dengan membutuhkan "<-
"; yaitu, 3 karakter termasuk spasi, bukan hanya "<-
".TRUE
oleh R. Jadi jika Anda bermaksud menguji jikax
kurang dari-y
, Anda dapat menulisif (x<-y)
yang tidak akan memperingatkan atau kesalahan, dan tampaknya berfungsi dengan baik. Tapi itu hanya akanFALSE
kapany=0
.=
dan menggunakannya<-
maka sulit untuk membantah bahwa langkah tambahangrep "[^<]<-[^ ]" *.R
tidak diperlukan.=
tidak perlu seperti itugrep
.<-
Anda jika Anda bisa menggunakannya=
? Dalam 99,99% kali=
tidak masalah. Kadang-kadang Anda membutuhkannya<<-
, yang merupakan sejarah yang berbeda.x = y = 5
setara denganx = (y = 5)
, karena operator penugasan "grup" kanan ke kiri, yang berfungsi. Artinya: menugaskan 5 key
, meninggalkan nomor 5; dan kemudian menetapkan bahwa 5 untukx
.Ini tidak sama dengan
(x = y) = 5
, yang tidak berfungsi! Artinya: tetapkan nilaiy
untukx
, meninggalkan nilaiy
; dan kemudian menetapkan 5 untuk, umm ..., apa sebenarnya?Saat Anda mencampur berbagai jenis operator penugasan,
<-
ikat lebih ketat dari=
. Jadix = y <- 5
diartikan sebagaix = (y <- 5)
, yang merupakan kasus yang masuk akal.Sayangnya,
x <- y = 5
ditafsirkan sebagai(x <- y) = 5
, yang merupakan kasus yang tidak berhasil!Lihat
?Syntax
dan?assignOps
untuk aturan prioritas (mengikat) dan pengelompokan.sumber
<- <<-
atas=
dalam tabel diutamakan, yang berarti<-
akan ditentukan terlebih dahulu. Jadi,x <- y = 5
harus dieksekusi sebagai(x <- y) = 5
.Menurut John Chambers, operator
=
hanya diperbolehkan di "tingkat atas," yang berarti tidak diperbolehkan dalam struktur kontrol sepertiif
, membuat kesalahan pemrograman berikut ini ilegal.Saat ia menulis, "Menolak formulir penugasan baru [=] dalam ekspresi kontrol menghindari kesalahan pemrograman (seperti contoh di atas) yang lebih mungkin dengan operator yang sama daripada dengan penugasan S lainnya."
Anda dapat melakukan ini jika "terisolasi dari struktur logis sekitarnya, dengan kawat gigi atau sepasang kurung tambahan," demikian juga
if ((x = 0)) 1 else x
akan berhasil.Lihat http://developer.r-project.org/equalAssign.html
sumber
x==0
hampir selalu berarti sebaliknya.x=0
sebagai tugas berakhirx<-0
!=
sesedikit mungkin karena=
dan==
terlihat sangat mirip.if(x = 0) 1 else x
melempar kesalahan, membantu saya menemukan dan memperbaiki bug.if(x <- 1) 1 else x
tidak melempar kesalahan dan sangat membingungkan.else
nilai, apakah Anda bermaksud menulis seperti itu?", Tetapi, itu mungkin mimpi pipa ...Operator
<-
dan=
menugaskan ke lingkungan di mana mereka dievaluasi. Operator<-
dapat digunakan di mana saja, sedangkan operator=
hanya diperbolehkan di tingkat atas (misalnya, dalam ekspresi lengkap yang diketik di command prompt) atau sebagai salah satu subekspresi dalam daftar ekspresi yang diperkuat.sumber
x <- 42
dengan sendirinya adalah pernyataan; diif (x <- 42) {}
dalamnya akan menjadi ekspresi, dan tidak valid. Agar jelas, ini tidak ada hubungannya dengan apakah Anda berada di lingkungan global atau tidak.1 + (x = 2)
function() x = 1
,repeat x = 1
,if (TRUE) x = 1
....Ini juga dapat menambah pemahaman tentang perbedaan antara kedua operator:
Untuk elemen pertama R telah menetapkan nilai dan nama yang tepat, sedangkan nama elemen kedua terlihat agak aneh.
R versi 3.3.2 (2016-10-31); macOS Sierra 10.12.1
sumber
data.frame
mencoba menggunakan nama variabel yang disediakan sebagai nama elemen dalam bingkai data)make.names("b <- rnorm(10)")
.