첫째, ifelse
는 은하지 항상 두 표현식을 평가 수행 - 테스트 벡터에서 모두 TRUE
및 FALSE
요소가있는 경우에만.
ifelse(TRUE, 'foo', stop('bar')) # "foo"
그리고 내 생각에
는 :
ifelse
하지는 벡터화되지 않은 상황에서 사용해야합니다. 그것은 항상 느린 더 오류가 발생하기 쉬운ifelse
/else
if
이상 사용 :하지만 벡터화 된 상황에서
# This is fairly common if/else code
if (length(letters) > 0) letters else LETTERS
# But this "equivalent" code will yield a very different result - TRY IT!
ifelse(length(letters) > 0, letters, LETTERS)
, ifelse
은 좋은 선택이 될 수 있습니다 -하지만 조심 결과의 길이 속성 수 있음 당신이 기대하는 것 (위와 같이, 나는 그 점에서 ifelse
이라고 생각합니다)이 아닙니다.
예를 들면 다음과 같습니다. tst
은 길이가 5이고 클래스가 있습니다. 나는 결과가 길이가 10이고 클래스가 없다고 기대할 것이다. 그러나 그것은 어떤 일이 일어나지 않는다. - 그것은 호환되지 않는 클래스와 길이 5를 얻는다.
# a logical vector of class 'mybool'
tst <- structure(1:5 %%2 > 0, class='mybool')
# produces a numeric vector of class 'mybool'!
ifelse(tst, 101:110, 201:210)
#[1] 101 202 103 204 105
#attr(,"class")
#[1] "mybool"
왜 길이가 10 일 것으로 예상됩니까? R "주기"에있는 대부분의 기능은 짧은 벡터가 더 이상 일치하기 때문에 :
1:5 + 1:10 # returns a vector of length 10.
...하지만 ifelse
에만 사이클에게 예를/인수는 TST 인수의 길이와 일치 없습니다.
이 아닌 클래스 (및 다른 속성)가이 아닌 테스트 객체에서 복사되는 이유는 무엇입니까? 논리 벡터를 반환하는 <
은 (일반적으로 숫자) 인수에서 클래스와 특성을 복사하지 않기 때문에. 그것은 일반적으로 매우 잘못 될 것이기 때문에 그렇게하지 않습니다.
1:5 < structure(1:10, class='mynum') # returns a logical vector without class
마지막으로, "스스로해라"하는 것이 더 효율적일까요?글쎄, ifelse
은 if
과 같은 프리미티브가 아니며, NA
을 처리하기 위해 특별한 코드가 필요합니다. NA
이 없으면 직접 할 수 있습니다.
tst <- 1:1e7 %%2 == 0
a <- rep(1, 1e7)
b <- rep(2, 1e7)
system.time(r1 <- ifelse(tst, a, b)) # 2.58 sec
# If we know that a and b are of the same length as tst, and that
# tst doesn't have NAs, then we can do like this:
system.time({ r2 <- b; r2[tst] <- a[tst]; r2 }) # 0.46 secs
identical(r1, r2) # TRUE
감사합니다. 지금은 이걸 볼 시간이 없지만 오늘 밤 나중에 할 것입니다. 의견 및 사례에 감사드립니다. –
훌륭한 조언과 예제. 감사! –
'ifelse'는 벡터 재활용을 수행합니다 -'yes' 또는'no' 변수 중 하나라도'test'와 길이가 같지 않으면 재활용됩니다. 즉, 예제의 끝에있는 테스트 코드는 모든 벡터의 길이가 동일한 경우에만 동일한 결과를 산출합니다. 예를 들어이 입력 데이터를보십시오 :'tst <- sample (c (TRUE, FALSE), 1e2, replace = TRUE); a <-1 : 100; b <- - (1:50); ' – Andrie