부울 연산자 && 및 ||


252

받는 따르면 R 언어 정의 의 차이 &&&(대응 |하고 ||), 후자는 아니지만 전자 벡터화된다는 것이다.

도움말 텍스트 에 따르면 , "And"와 "AndAlso"( "Or"및 "OrElse")의 차이점과 유사한 차이점을 읽습니다. 의미 : 모든 평가가 필요하지 않은 경우 (예 : A가 참이면 A 또는 B 또는 C는 항상 참이므로 A가 참인지 평가를 중단하십시오)

누군가 여기에서 빛을 비출 수 있습니까? 또한 R에 AndAlso와 OrElse가 있습니까?


또한 stackoverflow.com/q/6933598/210673stackoverflow.com/q/7953833/210673 (이제 복제본으로 닫힘) 에서 유사한 질문을 참조하십시오 .
Aaron

3
나는 &&와 || 다른 언어에서는 조건부 AND 및 OR 연산자, 논리 AND 또는 OR 부울 연산을 수행하지만 필요한 경우 두 번째 피연산자 만 평가합니다. R에서는 유용한 것을하지 마십시오.
skan

답변:


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.

마지막 차이점은 다음 &&과 같습니다. 그리고 ||필요한만큼의 용어 만 평가합니다 (단락이 의미하는 것 같습니다). 예를 들어, 다음은 정의되지 않은 값을 사용한 비교입니다 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 "라는 제목 의 R Inferno 섹션 8.2.17을 참조하십시오 .


길이 1의 논리를 비교하고 있습니다. 제어 흐름을 선호하는 이유에 대한 설명서는 명확하지 않습니다. @Theo의 답변에서 "단락"을 사용하므로 성능이 향상 되었습니까?
SFun28

아니. 짧은 형식 '&'만 사용하십시오. 단락 응답이 잘못되었습니다.
M. Tibbits

1
아니요, 단일 TRUE / FALSE 답변 만 보장하기 때문입니다. 더 짧은 양식은 결과를 초래할 수 c(TRUE, FALSE)있으며 if진술은 명확하지 않습니다. 모든 것이 1의 길이를 가지고 있다고 확신한다면, 그렇습니다. "단락"이 하나를 선호하는 이유라는 것이 맞습니다. 경고의 말이지 만, 길이가 하나만 될 수 있다는 것을 100 % 확신하십시오. 그렇지 않으면 구피 버그가 발생할 수 있습니다.
Aaron은 스택 오버플로를 떠났습니다.

9
@ SFun28 : 예. 단락은 흐름 제어에 선호되는 이유입니다. 더 나은 성능뿐만 아니라 모든 인수를 평가하지 않을 수도 있습니다. ?is.RR 또는 S-Plus를 실행 중인지 확인하기위한 표준 예제가 제공됩니다 . if(exists("is.R") && is.function(is.R) && is.R()). is.R존재하지 않는 경우 is.function(is.R)오류가 발생하므로 평가하고 싶지 않습니다 . 마찬가지로 is.R함수가 아닌 경우 처럼 함수를 호출하고 싶지 않습니다.
Richie Cotton

2
R 인페르노의 현재 버전에서 관련 섹션은 이제 8.2.17 "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

단락의 장점은 인수를 평가하는 데 시간이 오래 걸리는 경우에만 나타납니다. 일반적으로 인수가 더 큰 객체를 처리하거나 더 복잡한 수학적 연산을 수행하는 함수일 때 발생합니다.


"단락은"나에게 새로운 용어이지만, 그것을 설명하는 대답은 당신이 무슨 말을 동의 나에게 보인다 &&||.
Aaron은 스택 오버플로를 떠났습니다.

@DWin-길이가 1 인 논리를 처리하는 경우 동등합니까? 설명서에서 설명하는 것처럼 제어 흐름에서 선호되는 이유를 이해하려고합니다. 또한 R에는 "단락"구조가 있습니까?
SFun28

그들은이다 NOT 1> 길이의 벡터에 대한 동등한
M. Tibbits

2
인수 &&가 함수이고 첫 번째 인수 가 거짓이면 두 번째 인수 는 평가되지 않습니다. 어느 쪽이든 &또는 ifelse두 가지 주장을 모두 평가하는 것은 사실이 아닙니다 .
IRTFM

단락에 대한 Theo의 답변도 그렇지 않습니까?
아론은 스택 오버플로를 왼쪽

25

&&그리고 ||"단락"무엇을라고합니다. 즉, 첫 번째 피연산자가 식의 값을 결정하기에 충분하면 두 번째 피연산자를 평가하지 않습니다.

행의 첫 번째 피연산자는 예를 들어 &&거짓 다음의 식의 값을 변경 (수 없기 때문에, 두 번째 피연산자 평가 소용 없다 false && true하고 false && false모두 거짓). 동일은 간다 ||첫 번째 피연산자에 해당하는 경우.

당신은 더 이것에 대해 여기 읽을 수 있습니다 : http://en.wikipedia.org/wiki/Short-circuit_evaluation을 테이블에서 해당 페이지에 당신이 볼 수 &&에 해당 AndAlso난 당신이 언급하는 가정 VB.NET,있다.


3
이것은 단락되었다는 증거로 충분해야합니다 f <- function() { print('hello'); TRUE }; FALSE && f(). &기능이 평가되고 변경 되었음을 확인하십시오. QED.
Theo

2
테오는, 그래, 당신은 정확 &&하고 ||단락. 그러나 그것은 짧은 형식과 긴 형식을 비교할 때 실제로 아주 작은 부분입니다. 입력이 벡터 일 때 각각의 기능을 이해하는 것이 훨씬 더 중요합니다.
Aaron은 Stack Overflow를

2
@MTibbits 사실 이것은 완전한 답은 아니지만 단락에 대한 설명 은 정확합니다 . 시도 F & {message("Boo!");T}F && {message("Boo!");T}.
mbq
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.