1. ホーム
  2. r

[解決済み] Rの代入演算子"="と"<-"の違いは何ですか?

2022-03-17 23:15:05

質問

代入演算子の違いは何ですか? =<- をRで使うか?

この例のように、演算子が若干異なることは承知しています。

x <- y <- 5
x = y = 5
x = y <- 5
x <- y = 5
# Error in (x <- y) = 5 : could not find function "<-<-"

しかし、違いはこれだけなのでしょうか?

解決方法は?

<ブロッククオート

代入演算子の違いを教えてください。 =<- をRで使うか?

例にあるように =<- は演算子の優先順位(同じ式に混在する場合の評価順序を決める)が若干異なる。実際には ?Syntax をRで実行すると、次のような演算子優先順位表が得られます(高い方から低い方へ)。

…
‘-> ->>’           rightwards assignment
‘<- <<-’           assignment (right to left)
‘=’                assignment (right to left)
…

しかし、違いはこれだけなのでしょうか?

というご質問でしたので 代入演算子 はい、そこが唯一の違いです。しかし、そうでないと信じられても仕方がないでしょう。のRのドキュメントでさえ ?assignOps は、もっと違いがあると主張しています。

オペレーターは <- はどこでも使える。 一方、演算子 = はトップレベルでのみ許可されます(例. コマンドプロンプトで入力された完全な式)または を、中括弧で囲まれた式のリストの中の部分式で表現します。

あまり細かいことは言わないようにしましょう。 Rのドキュメントは間違っている . これは簡単に示すことができます。 = 演算子で、(a) トップレベルでもなく、(b) 中括弧付きのリストの中の部分式でもないもの(つまり {…; …} ). - 早速ですが

x
# Error: object 'x' not found
sum((x = 1), 2)
# [1] 3
x
# [1] 1

を使用して、明らかに割り当てを実行しました。 = (a)と(b)の文脈の外側にある。では、なぜR言語の中心的な機能のドキュメントが何十年も間違っているのでしょうか?

それは、Rの構文において、シンボル = は2つの異なる意味を持ち、日常的に混同されています(上に引用したドキュメントを含め、専門家でさえもそうです)。

  1. 1つ目の意味は 代入演算子 . ここまでの話はこれだけです。
  2. 2つ目の意味は、演算子ではなく 構文トークン を通知するものです。 名前付き引数渡し を関数呼び出しで使用します。とは異なり = 演算子 は実行時に何もせず、単に式のパース方法を変更するだけです。

では、R はどのようにして、ある使い方の = は演算子なのか名前付き引数渡しなのか?見てみよう。

一般的な形式のコードで ...

‹function_name›(‹argname› = ‹value›, …)
‹function_name›(‹args›, ‹argname› = ‹value›, …)

... = は、名前付き引数の受け渡しを定義するトークンです:それは ではなく 代入演算子。さらに = は完全に 禁じられた は、ある構文コンテキストでは

if (‹var› = ‹value›) …
while (‹var› = ‹value›) …
for (‹var› = ‹value› in ‹value2›) …
for (‹var1› in ‹var2› = ‹value›) …

これらのいずれかを使用すると、「'bla' の予期せぬ '=' 」というエラーが発生します。

それ以外の文脈では = は、代入演算子の呼び出しを指します。特に、部分式を括弧で囲むだけで、上記の(a)は有効、(b)は 代入 . 例えば、以下は代入を行う。

median((x = 1 : 10))

でも、また

if (! (nf = length(from))) return()

<サブ さて、このようなコードは非道だと反論されるかもしれません(その通りかもしれません)。しかし、私はこのコードを base::file.copy 関数に置き換えます。 <-= ) - これはRのコアコードベースの多くに広まっているパターンです。

ジョン・チェンバースによる原文の説明 Rのドキュメントがおそらくベースにしているもので、実際にこのことを正しく説明しています。

<ブロッククオート

[ = トップレベル(完全なプログラムまたはユーザータイプ式として)、および中括弧または追加の括弧によって周囲の論理構造から分離された場合です。


まとめると、デフォルトでは演算子 <-= は同じことをします。しかし、どちらかが オーバーライド を別途作成し、その動作を変更することができます。それに対して <--> (左から右への代入) は、構文的には異なるものですが、常に 同じ 関数を使用します。一方をオーバーライドすると、もう一方もオーバーライドされます。これを知っていても、実用的であることはほとんどありません が、それは できる 戯れに使える .