Оценка ряда критериев с вложенными ifs в R - есть ли лучший способ? - PullRequest
3 голосов
/ 13 мая 2011

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

Эта функция хорошо работает для меня - я проверил ее по тысячам тестов, и она достаточно быстра для любого броскана него.Однако я хотел бы объединить его и несколько аналогичных функций в пакет для более широкого использования, и я хотел бы получить некоторые отзывы об этом, прежде чем сделать это:

  1. Функция зависит от большого цикла for, обернутого вокруг вложенных функций if-else.Это не особенно элегантно, и ужас for(), несомненно, подрывает мое доверие к некоторым (хм), но это работает.Есть ли лучший подход к этому?Если да, то достаточно ли оправдать переписывание Code That Works?

  2. Критерии в приведенной выше функции предназначены для интерпретации теста в Северной Америке;остальной мир следует немного другим стандартам.Я бы тоже хотел, чтобы они были в наличии.Я рассматриваю возможность создания отдельной неэкспортируемой функции для каждого.Различные проверки данных (исключенные из приведенной выше сущности) будут продолжать действовать в основной функции, которая затем будет вызывать указанную подфункцию.Это звучит разумно?

  3. Любые другие предложения или советы?Стиль, организация кода - все что угодно.

Я понимаю, что, вероятно, мне следует просто вытолкнуть эту птенца из гнезда, но я работаю в основном в вакууме и поэтому немного нервничаю.Любой совет очень ценится.

Редактировать: если вы пропустили ссылку на суть, это функция, о которой я говорю .


Какзапрошено образец данных испытаний .

Ответы [ 3 ]

4 голосов
/ 13 мая 2011

Отредактировано для отражения комментариев и проверки по тестовым данным

Вы можете избежать любого типа цикла или 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
4 голосов
/ 13 мая 2011
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"
1 голос
/ 13 мая 2011

Если вам не нужен цикл for, используйте apply с функцией, написанной для возврата интерпретации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...