Булевы операторы && и || - PullRequest
219 голосов
/ 02 июля 2011

Согласно определению языка R , разница между & и && (соответственно | и ||) заключается в том, что первое векторизовано, а второе - нет.

Согласно тексту справки я прочел разницу, аналогичную разнице между «И» и «И также» (соответственно «И» и «OrElse») ... Имея в виду: Это не все оценки, если они не должны быть (т.е. A или B или C всегда верны, если A истинно, поэтому прекратите оценку, если A истинно)

Может ли кто-нибудь пролить свет здесь? Кроме того, есть ли And R и OrElse в R?

Ответы [ 3 ]

308 голосов
/ 02 июля 2011

Более короткие из них векторизованы, что означает, что они могут возвращать вектор, например так:

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

Более длинная форма оценивает слева направо, рассматривая только первый элемент каждого вектора, поэтому приведенное выше дает

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

Как говорится на странице справки, это делает более длинную форму "подходящей для программирования потока управления и обычно предпочтительной в выражениях if."

Таким образом, вы хотите использовать длинные формытолько когда вы уверены, что векторы имеют длину один.

Вы должны быть абсолютно , определенные ваши векторы имеют только длину 1, например, в случаях, когда они являются функциями, которые возвращают только логические значения длины 1.Вы хотите использовать короткие формы, если векторы имеют длину, возможно,> 1.Так что, если вы не совсем уверены, вам следует сначала проверить или использовать краткую форму, а затем использовать all и any, чтобы уменьшить ее до длины для использования в операторах потока управления, например if.

Функции all и any часто используются в результате векторизованного сравнения, чтобы увидеть, являются ли все или какие-либо из сравнений истинными, соответственно.Результаты этих функций обязательно имеют длину 1, поэтому они подходят для использования в предложениях if, а результаты векторизованного сравнения - нет.(Хотя эти результаты были бы подходящими для использования в ifelse.

Одно заключительное отличие: && и || оценивают только столько терминов, сколько им нужно (что, по-видимому, означаеткороткое замыкание). Например, вот сравнение с использованием неопределенного значения 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

Наконец, см. Раздел 8.2.17 в R Inferno , озаглавленный «и и and and».

29 голосов
/ 02 июля 2011

Ответ о «коротком замыкании» потенциально вводит в заблуждение, но имеет некоторую правду (см. Ниже).В языке 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
21 голосов
/ 02 июля 2011

&& и || - это то, что называется "коротким замыканием". Это означает, что они не будут оценивать второй операнд, если первого операнда достаточно для определения значения выражения.

Например, если первый операнд для && является ложным, тогда нет смысла оценивать второй операнд, поскольку он не может изменить значение выражения (false && true и false && false оба являются ложными). То же самое относится к ||, когда первый операнд истинен.

Вы можете узнать больше об этом здесь: http://en.wikipedia.org/wiki/Short-circuit_evaluation Из таблицы на этой странице вы можете видеть, что && эквивалентно AndAlso в VB.NET, который, как я полагаю, вы имеете в виду.

...