2011-05-12 3 views
3

많은 연구가 결핵 진단 테스트를 중심으로 진행됩니다. 예상대로 테스트 결과를 신속하게 평가하고 검증 할 수 있으면 편리합니다. 나는 그 일을하는 함수를 작성했다. here (명료성을 위해 아래로 내려 간다.) 간단히 말해서, 그것은 테스트의 숫자 결과를 취하고 제조업체 지정 해석을 생성합니다.R에서 중첩 된 if와 함께 일련의 기준을 평가하는 것이 더 좋은 방법일까요?

이 함수는 잘 작동합니다. 수천 개의 테스트에 대해 유효성을 검사했으며, 내가 던지는 모든 것에 대해 충분히 빠릅니다. 나는 그러나, 넓은 사용을위한 패키지로 유사한 기능의 몇 가지를 번들하고 싶습니다, 그리고 내가 그렇게하기 전에 일부 피드백을 얻을 싶습니다

  1. 기능이에 따라 달라집니다 중첩 된 if-else 함수를 감싸는 루프에 아주 좋습니다. 그것은 특히 우아하지 않고 두려움은 의심 할 여지없이 일부 (에헴)와 내 신뢰성을 손상하지만, 그것은 작동합니다. 이것에 대한 더 나은 접근법이 있습니까? 그렇다면, 작동하는 코드 다시 작성을 보증하는 것이 충분합니까?

  2. 위 기능의 기준은 북미 지역의 테스트를 해석하기위한 것입니다. 나머지 세계는 약간 다른 표준을 따릅니다. 나는 그것들을 사용할 수있게하고 싶습니다. 나는 각각에 대해 별도의 수출되지 않은 기능을 고려하고있다. 위의 요지에서 제외 된 다양한 데이터 검사는 main 함수에 계속 살며 지정된 함수를 호출합니다. 그게 합리적이라고 생각하니?

  3. 다른 제안이나 조언이 있으십니까? 스타일, 코드 구성 - 전혀 없습니다.

나는이 아기 새를 둥지에서 밀어 내야한다고 생각하지만, 대부분 진공 상태에서 일하기 때문에 약간 긴장됩니다. 어떤 조언을 크게 주시면 감사하겠습니다.

편집 : 요점에 대한 링크를 놓친 경우를 대비하여 this is the function I'm talking about.


요청시, sample test data.

+0

잠재적으로 변화하는 기준을 8, .25 등의 하드 코드 된 값입니까? 또는 예 : 중간? 또는 다른 것? – geoffjentry

+0

변경 사항을 테스트 할 수 있도록 예제 데이터와 예상 결과를 게시 할 수 있습니까? – Andrie

+0

실제로 전 세계적인 기준을 살펴본 후 잠시 지났습니다. 북미에서만 유일한 기준 (23-26 행) 인 것처럼 보입니다. 그만큼 쉽게 토글 할 수 있습니다. 그러나 다른 그룹 (예 : 면역 저하 환자)에 대한 다른 기준 세트 나 연구에서 개발 된 대체 기준을 추가하고 싶을 수도 있습니다. –

답변

4

편집 의견을 반영하고 당신은 모두 루프 또는 if의 모든 유형을 방지하고 단순히 R 벡터 첨자를 사용할 수 있습니다

테스트 데이터에 대한 유효성을 검사 :

qft.interp <- function(nil, tb, mitogen, tbnil.cutoff = 0.35){ 

    # Set a tolerance to avoid floating point comparison troubles. 
    tol <- .Machine$double.eps^0.5 

    # Set up the results vector 
    result <- rep(NA, times = length(nil)) 
    result[nil+tol > 8.0] <- "Indeterminate" 
    result[is.na(result) & (tb-nil+tol > tbnil.cutoff) & 
      (tb-nil+tol > .25*nil)] <- "Positive" 
    result[is.na(result) & (tb-nil+tol < tbnil.cutoff | tb-nil+tol < .25*nil) & 
     !(mitogen-nil+tol < 0.5)] <- "Negative" 
    result[is.na(result) & ((tb-nil+tol < tbnil.cutoff | tb-nil+tol < .25*nil) & 
      mitogen-nil+tol < 0.5)] <- "Indeterminate" 
    result 
} 

all(with(tests, qft.interp(nil, tb, mitogen)) == tests$interp) 

[1] TRUE 
+0

샘플 데이터가 추가되었습니다! 제안 해 주셔서 감사합니다. –

+3

완전히 벡터화 된 솔루션을 얻으려면 인스턴스 중 일부를 잘라내야하지만 이것이 가장 깨끗한 방법이라고 생각합니다. 코멘트에서 작동하지 않는 아래의 내용을보십시오. –

+0

이 접근법의 문제점은 나중 = 9.41, tb = 6.73, mitogen = 10 인 샘플 데이터에서 나중의 기준으로 덮어 쓸 수 있다는 것입니다. 이것은 원래 (정확하게) 불확정으로 설정되었지만 나중에 부정으로 바뀌었다. 원본의'if()'흐름은 이것을 막습니다. –

1

for 루프를 사용하지 않으려면 apply 함수를 사용하여 해석을 반환하십시오.

+0

이것만으로도 내가 글을 게시하게되어 기쁩니다. 항상 항상 잊어 버려요 ... –

+2

'apply'는'for'의 단지 예쁜 형태이며 일반적으로 더 빠르지 않습니다. – Henry

+0

맞습니다. 그래서 잊어 버리는 경향이 있습니다. 속도는 실제로 여기서 중요하지 않습니다. 어쨌든 - 이미 충분히 빠릅니다. 그래도 꽤 좋다. –

4
result[ nil + (tol > 8.0)] <- "Indeterminate" 
result[(tb - nil + (tol > tbnil.cutoff)) & (tb - nil + (tol > .25 * nil))] <- "Positive" 
result[ (tb - nil + (tol < tbnil.cutoff))| (tb - nil + (tol < .25 * nil)) & 
         !(mitogen - nil + tol < 0.5) ] <- "Negative" 
result[ (tb - nil + (tol < tbnil.cutoff)) | (tb - nil + (tol < .25 * nil)) & 
          (mitogen - nil + (tol < 0.5)) ] <- "Indeterminate" 
+0

의견을 보내 주셔서 감사합니다. 매트 파커 (Matt Parker)는 MECE가 아니라는 의견에 주목하여 일부 테스트에'! is.na (result) '를 추가해야합니다. 내 업데이트 답변을 참조하십시오. – Andrie

+0

@Andrie : 당신이 그것을 확인해 주셨습니다. 나는 그들이 정말로 상호 배타적인지 궁금해했다. 나는 코드를 강화하는 것이 바람직하다고 생각한다. –

관련 문제