Programing

왜`vapply`가`sapply`보다 안전한가요?

lottogame 2020. 10. 6. 07:42
반응형

왜`vapply`가`sapply`보다 안전한가요?


문서에 따르면

vapply와 유사 sapply하지만 미리 지정된 반환 값 유형이 있으므로 사용하는 것이 [...] 더 안전 할 수 있습니다.

왜 그것이 일반적으로 더 안전한지에 대해 자세히 설명해 주시겠습니까?


추신 : 나는 답을 알고 있으며 이미 피하는 경향이 sapply있습니다. 여기에 좋은 대답이 있었으면 좋겠어요. 그래서 동료들에게 알려줄 수 있습니다. 제발 "매뉴얼을 읽어라"라고 대답하지 마십시오.


이미 언급했듯이 vapply두 가지 작업을 수행합니다.

  • 약간의 속도 향상
  • 제한된 반환 유형 검사를 제공하여 일관성을 향상시킵니다.

두 번째 요점은 오류가 발생하기 전에 오류를 포착하고 더 강력한 코드로 이어지기 때문에 더 큰 이점입니다. 이 반환 값 검사 는 반환 값이 예상 한 것과 일치하는지 확인하기 위해 sapplyfollowed 를 사용하여 개별적으로 수행 할 수 stopifnot있지만 vapply조금 더 쉽습니다 (사용자 지정 오류 검사 코드가 범위 내의 값을 검사 할 수 있기 때문에 더 제한적일 경우 등). ).

다음 vapply은 결과가 예상대로인지 확인 하는 예입니다 . 이것은 내가 PDF 스크래핑 동안 방금 작업했던 것과 유사합니다. 여기서 findD사용하여 원시 텍스트 데이터의 패턴 을 일치시킵니다 (예 : 엔티티 별 목록이 있고 각 엔티티 내의 주소와 일치하는 정규식이 있습니다. PDF는 순서가 맞지 않게 변환되었으며 엔티티에 대해 두 개의 주소가있어 불량을 일으켰습니다.)split

> input1 <- list( letters[1:5], letters[3:12], letters[c(5,2,4,7,1)] )
> input2 <- list( letters[1:5], letters[3:12], letters[c(2,5,4,7,15,4)] )
> findD <- function(x) x[x=="d"]
> sapply(input1, findD )
[1] "d" "d" "d"
> sapply(input2, findD )
[[1]]
[1] "d"

[[2]]
[1] "d"

[[3]]
[1] "d" "d"

> vapply(input1, findD, "" )
[1] "d" "d" "d"
> vapply(input2, findD, "" )
Error in vapply(input2, findD, "") : values must be length 1,
 but FUN(X[[3]]) result is length 2

제가 학생들에게 말했듯이, 프로그래머가되는 것은 당신의 사고 방식을 "오류는 성가시다"에서 "오류는 내 친구"로 바꾸는 것입니다.

길이가 0 인 입력
한 가지 관련된 점은 입력 길이가 0이면 sapply입력 유형에 관계없이 항상 빈 목록을 반환한다는 것입니다. 비교:

sapply(1:5, identity)
## [1] 1 2 3 4 5
sapply(integer(), identity)
## list()    
vapply(1:5, identity)
## [1] 1 2 3 4 5
vapply(integer(), identity)
## integer(0)

를 사용하면 vapply특정 유형의 출력이 보장되므로 길이가 0 인 입력에 대해 추가 검사를 작성할 필요가 없습니다.

벤치 마크

vapply 결과가 예상되는 형식을 이미 알고 있기 때문에 조금 더 빠를 수 있습니다.

input1.long <- rep(input1,10000)

library(microbenchmark)
m <- microbenchmark(
  sapply(input1.long, findD ),
  vapply(input1.long, findD, "" )
)
library(ggplot2)
library(taRifx) # autoplot.microbenchmark is moving to the microbenchmark package in the next release so this should be unnecessary soon
autoplot(m)

자동 플롯


과 관련된 추가 키 입력 vapply은 나중에 혼란스러운 결과를 디버깅하는 시간을 절약 할 수 있습니다. 호출하는 함수가 다른 데이터 유형을 반환 할 수 있다면 vapply반드시 사용해야합니다.

떠오르는 한 가지 예 sqlQueryRODBC패키지에 있습니다. 쿼리를 실행하는 동안 오류가 발생하면이 함수는 character메시지와 함께 벡터를 반환 합니다. 예를 들어, 테이블 이름의 벡터를 반복하고 tnames각 테이블의 숫자 열 'NumCol'에서 최대 값을 다음과 같이 선택한다고 가정합니다.

sapply(tnames, 
   function(tname) sqlQuery(cnxn, paste("SELECT MAX(NumCol) FROM", tname))[[1]])

모든 테이블 이름이 유효하면 numeric벡터 가 생성됩니다 . 그러나 테이블 이름 중 하나가 데이터베이스에서 변경되고 쿼리가 실패하면 결과가 mode로 강제 변환됩니다 character. 그러나 vapplywith를 사용하면 FUN.VALUE=numeric(1)여기에서 오류가 중지되고 줄 아래 어딘가에 표시되는 것을 방지 할 수 있습니다.


당신이 항상 당신의 결과가 특별한 무언가가되기를 원한다면 ... 예를 들어 논리적 인 벡터. vapply이것이 발생하는지 확인하지만 sapply반드시 그런 것은 아닙니다.

a<-vapply(NULL, is.factor, FUN.VALUE=logical(1))
b<-sapply(NULL, is.factor)

is.logical(a)
is.logical(b)

참고 URL : https://stackoverflow.com/questions/12339650/why-is-vapply-safer-than-sapply

반응형