ブール演算子&&および||


252

R言語の定義によれば、&andと&&(それに対応|して||)の違いは、前者はベクトル化されているが、後者はベクトル化されていないことです。

ヘルプテキストによると「And」と「AndAlso」の違いに相当する違いを読みました(対応して「Or」と「OrElse」)... (Aがtrueの場合、AまたはBまたはCは常にtrueであるため、Aがtrueかどうかの評価を停止します)

誰かがここで光を当てることができますか?また、RにはAndAlsoとOrElseがありますか?


また、stackoverflow.com / q / 6933598/210673およびstackoverflow.com/q/7953833/210673で同様の質問を参照してください(現在は重複としてクローズされています)。
アーロンがスタックオーバーフローを去った

3
&&と|| 他の言語では条件付きANDおよびOR演算子であり、論理ANDまたはORブール演算を実行しますが、必要な場合にのみ2番目のオペランドを評価します。Rでは、有用なことは何もしません。
skan 2016年

回答:


340

短い方はベクトル化されています。つまり、次のようにベクトルを返すことができます。

((-2:2) >= 0) & ((-2:2) <= 0)
# [1] FALSE FALSE  TRUE FALSE FALSE

長い形式は、各ベクトルの最初の要素のみを調べて、左から右に評価するため、上記は

((-2:2) >= 0) && ((-2:2) <= 0)
# [1] FALSE

ヘルプページにあるように、これにより長い形式が「制御フローのプログラミングに適切になり、if句で一般的に推奨されます」になります。

したがって、ベクトルが長さ1であることが確実な場合にのみ、長い形式を使用する必要があります。

あなたはする必要があります絶対に彼らはそのリターンだけで長さ1つのブール関数であるあなたのベクトルは、このような場合にのみと長さ1、ある特定。ベクトルの長さがおそらく1より大きい場合は、短い形式を使用します。したがって、確実でない場合は、最初に確認するか、短い形式を使用allしてanyから、を使用して、のような制御フローステートメントで使用できるように長さを短くする必要がありifます。

関数allanyは、ベクトル化された比較の結果に対してよく使用され、比較のすべてまたはいずれかがそれぞれ真であるかどうかを確認します。これらの関数の結果は必ず長さ1になるので、if句での使用に適していますが、ベクトル化された比較の結果はそうではありません。(ただし、これらの結果はでの使用に適していますifelse

最後の1つの違い:とは&&||必要な数の用語のみを評価します(これは、短絡の意味するようです)。たとえば、次は未定義の値を使用した比較ですa。それは、ショートなかったとして場合&|ない、それはエラーを与えるだろう。

a
# Error: object 'a' not found
TRUE || a
# [1] TRUE
FALSE && a
# [1] FALSE
TRUE | a
# Error: object 'a' not found
FALSE & a
# Error: object 'a' not found

最後に、「and and andand」というタイトルのThe R Infernoのセクション8.2.17を参照してください。


長さ1の論理を比較しています。ドキュメントでは、なぜ制御フローに適しているかについて明確ではありません。それは、@ Theoの回答からの「短絡」を使用しているため、パフォーマンスが向上しているためですか?
SFun28

いいえ。「&」という短い形式を使用してください-短絡の答えは正しくありません。
M.ティビッツ

1
いいえ、TRUE / FALSEの答えが1つしかないことが保証されているためです。短い形式ではが発生する可能性がc(TRUE, FALSE)あり、ifステートメントは明確ではありません。すべての長さが1であると確信している場合は、はい、どちらでも可能であり、「短絡」が優先される理由であることは間違いありません。ただし、警告として、長さは1つしか指定できないことを100%確認してください。そうでなければ本当に間抜けなバグを得ることができます。
アーロンは

9
@ SFun28:はい、短絡がフロー制御に好まれた理由です。パフォーマンスが向上するだけでなく、すべての引数を評価したくない場合があります。?is.RRまたはS-Plusを実行しているかどうかを確認するための標準的な例を示します。 if(exists("is.R") && is.function(is.R) && is.R())is.R存在しない場合はis.function(is.R)、エラーがスローされるため、評価する必要はありません。同様に、is.Rが関数でない場合は、関数であるかのように呼び出す必要はありません。
リッチーコットン

2
Rインフェルノの現在のバージョンでは、関連するセクションは8.2.17 "and and andand"になりました
Silverfish

34

「短絡」に関する答えは誤解を招く可能性がありますが、いくつかの真実があります(以下を参照)。R / S言語では、&&||だけ最初の引数の最初の要素を評価します。ベクトルまたはリスト内の他のすべての要素は、最初の要素の値に関係なく無視されます。これらの演算子はで動作するように設計されてif (cond) {} else{}...建設と直接プログラム制御ではなく、構造新しいベクトルに&し、|彼らはの長さに沿って、いわば、「並列に」適用されるので、オペレータは、ベクトル上で動作するように設計されています最長の引数。比較を行う前に、両方のベクトルを評価する必要があります。ベクトルが同じ長さでない場合は、短い方の引数のリサイクルが実行されます。

&&またはへの引数||が評価されると、「短絡」が発生し、左から右に連続する値のいずれかが決定的である場合、評価は中止され、最終的な値が返されます。

> if( print(1) ) {print(2)} else {print(3)}
[1] 1
[1] 2
> if(FALSE && print(1) ) {print(2)} else {print(3)} # `print(1)` not evaluated
[1] 3
> if(TRUE && print(1) ) {print(2)} else {print(3)}
[1] 1
[1] 2
> if(TRUE && !print(1) ) {print(2)} else {print(3)}
[1] 1
[1] 3
> if(FALSE && !print(1) ) {print(2)} else {print(3)}
[1] 3

短絡の利点は、引数の評価に時間がかかる場合にのみ現れます。これは通常、引数がより大きなオブジェクトを処理するか、より複雑な数学演算を行う関数である場合に発生します。


「短絡は、」私には新しい用語であるが、答えは、それを記述していることに私には思えるについて、あなたは言うことと一致している&&||
アーロンは

@DWin-長さ1の論理を超える演算子の場合、それらは同等ですよね?ドキュメントに記載されているように、これらが制御フローで推奨される理由を理解しようとしています。また、Rには「短絡」構造がありますか?
SFun28

彼らはありません 1>長さのベクトルのための同等
M. Tibbits

2
toの引数&&が関数で、最初の引数がfalseの場合、2番目の引数は評価されないのは事実です。それはどちらかのために真実ではないです&か、ifelseその両方の引数を評価します。
IRTFM

テオの短絡に関する答えもそうではありませんか?
アーロンがスタックオーバーフローを去った

25

&&そして||「短絡」何と呼ばれています。つまり、最初のオペランドが式の値を決定するのに十分である場合、2番目のオペランドは評価されません。

最初のオペランドは、たとえば&&偽それは式の値を変更する(ことができないので、第二オペランドを評価するにはポイントが存在しないfalse && truefalse && falseの両方偽です)。同じことがのために行く||最初のオペランドがtrueの場合。

詳細については、こちらをご覧ください。http//en.wikipedia.org/wiki/Short-circuit_evaluationそのページの表&&からAndAlso、VB.NET と同等であることがわかります。


3
これは、短絡していることの証明になるはずですf <- function() { print('hello'); TRUE }; FALSE && f()。への変更&、関数が評価されることを確認します。QED。
Theo

2
テオ、そう、あなたは正しい &&||短絡。しかし、これは、短い形式と長い形式を比較すると、かなり重要な点です。入力がベクトルの場合、それぞれが何をするかを理解することははるかに重要です。
アーロンがスタックオーバーフローを去った

2
@MTibbits実際、これは完全な答えではありませんが、短絡に関する記述は正しいです。やってみF & {message("Boo!");T}F && {message("Boo!");T}
mbq 2011
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.