R言語の定義によれば、&
andと&&
(それに対応|
して||
)の違いは、前者はベクトル化されているが、後者はベクトル化されていないことです。
ヘルプテキストによると、「And」と「AndAlso」の違いに相当する違いを読みました(対応して「Or」と「OrElse」)... (Aがtrueの場合、AまたはBまたはCは常にtrueであるため、Aがtrueかどうかの評価を停止します)
誰かがここで光を当てることができますか?また、RにはAndAlsoとOrElseがありますか?
R言語の定義によれば、&
andと&&
(それに対応|
して||
)の違いは、前者はベクトル化されているが、後者はベクトル化されていないことです。
ヘルプテキストによると、「And」と「AndAlso」の違いに相当する違いを読みました(対応して「Or」と「OrElse」)... (Aがtrueの場合、AまたはBまたはCは常にtrueであるため、Aがtrueかどうかの評価を停止します)
誰かがここで光を当てることができますか?また、RにはAndAlsoとOrElseがありますか?
回答:
短い方はベクトル化されています。つまり、次のようにベクトルを返すことができます。
((-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
ます。
関数all
とany
は、ベクトル化された比較の結果に対してよく使用され、比較のすべてまたはいずれかがそれぞれ真であるかどうかを確認します。これらの関数の結果は必ず長さ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を参照してください。
c(TRUE, FALSE)
あり、if
ステートメントは明確ではありません。すべての長さが1であると確信している場合は、はい、どちらでも可能であり、「短絡」が優先される理由であることは間違いありません。ただし、警告として、長さは1つしか指定できないことを100%確認してください。そうでなければ本当に間抜けなバグを得ることができます。
?is.R
RまたはS-Plusを実行しているかどうかを確認するための標準的な例を示します。 if(exists("is.R") && is.function(is.R) && is.R())
。is.R
存在しない場合はis.function(is.R)
、エラーがスローされるため、評価する必要はありません。同様に、is.R
が関数でない場合は、関数であるかのように呼び出す必要はありません。
「短絡」に関する答えは誤解を招く可能性がありますが、いくつかの真実があります(以下を参照)。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
短絡の利点は、引数の評価に時間がかかる場合にのみ現れます。これは通常、引数がより大きなオブジェクトを処理するか、より複雑な数学演算を行う関数である場合に発生します。
&&
と||
。
&&
が関数で、最初の引数がfalseの場合、2番目の引数は評価されないのは事実です。それはどちらかのために真実ではないです&
か、ifelse
その両方の引数を評価します。
&&
そして||
「短絡」何と呼ばれています。つまり、最初のオペランドが式の値を決定するのに十分である場合、2番目のオペランドは評価されません。
最初のオペランドは、たとえば&&
偽それは式の値を変更する(ことができないので、第二オペランドを評価するにはポイントが存在しないfalse && true
とfalse && false
の両方偽です)。同じことがのために行く||
最初のオペランドがtrueの場合。
詳細については、こちらをご覧ください。http://en.wikipedia.org/wiki/Short-circuit_evaluationそのページの表&&
からAndAlso
、VB.NET と同等であることがわかります。
f <- function() { print('hello'); TRUE }; FALSE && f()
。への変更&
、関数が評価されることを確認します。QED。
&&
と||
短絡。しかし、これは、短い形式と長い形式を比較すると、かなり重要な点です。入力がベクトルの場合、それぞれが何をするかを理解することははるかに重要です。
F & {message("Boo!");T}
てF && {message("Boo!");T}
。