Моя пользовательская функция с вложенными операторами if неправильно оценивает векторные входы в R - помогите - PullRequest
0 голосов
/ 28 октября 2011

Я пытаюсь создать функцию, которая показывает, сколько «человеко-лет» человек внес в данную возрастную группу в данный период.Если человек жив в течение указанного интервала, он вносит свой вклад в интервал времени.Например, для возрастной группы 0-1 человек, находившийся под наблюдением в возрасте 0,5 года и оставленный в возрасте 3 лет, внесет 0,5 года в человеко-годы в возрастной группе 0-1 года.

Мне удалось успешно запустить этот код в цикле for, но это занимает вечность, поэтому я пытаюсь реализовать векторную функцию.Функция прекрасно работает для отдельных записей, но не может обрабатывать векторы, которые я передаю ей, выдавая ошибку: «... условие имеет длину> 1, и будет использоваться только первый элемент» *

Функция Iнаписано следующее:

pyears01.smm <- function(ageent, ageleave) {
if ( is.na(ageent) | is.na(ageleave) ) 
    {NA} else
if( ageent > 1 )
    {0} 
if ( ageent <= 1 && ageleave > 1 ) 
    {1-ageent} else
if( ageent <= 1 && ageleave <= 1 ) 
    {ageleave-ageent} 
}

, который отлично работает для оценки следующего:

pyears.smm(0,5)
[1] 1
pyears.smm(0.5,0.75)
[1] 0.25
pyears.smm(2,3)
[1] 0

, но неправильно оценивает NA:

> pyears.smm(NA,NA)
[1] 0
> pyears.smm("NA",5)
[1] 0

инеправильно обрабатывает векторы:

x <- c(0,0.5,2,5)
y <- c(5,0.75,3,NA)
z<- pyears.smm(x,y)
Warning message:
In if (!is.na(ageent) & ageent <= 1 & !is.na(ageleave) & ageleave >  :
  the condition has length > 1 and only the first element will be used
> z
[1]  1.0  0.5 -1.0 -4.0

Я читал, что elseif принимает векторы, в то время как подобные операторы могут оценивать только отдельные элементы, но у меня есть несколько уровней вложенных операторов if, поэтому я не уверенкак это исправить.Мы ценим любые предложения.Спасибо!

Ответы [ 3 ]

3 голосов
/ 28 октября 2011

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

pyears01.smm2 <- function(ageent, ageleave){
    ifelse(is.na(ageent) | is.na(ageleave), NA
    , ifelse(ageent > 1,0
    , ifelse(ageent <= 1 & ageleave > 1, 1 - ageent, ageleave - ageent)))
}

> pyears01.smm2(NA, NA)
[1] NA
> pyears01.smm2(NA, 5)
[1] NA
> x <- c(0,0.5,2,5)
> y <- c(5,0.75,3,NA)
> pyears01.smm2(x,y)
[1] 1.00 0.25 0.00   NA

Если вы в Google или ищете в SO различия между if else и ifelse(), я уверен, что вы найдете что-то хорошее. Вот одна ссылка, которая поднялась наверх: http://rwiki.sciviews.org/doku.php?id=tips:programming:ifelse

2 голосов
/ 28 октября 2011

Векторизованная форма конструкции if - else равна ifelse (не иначе). Тем не менее, вам не нужно это для этого упражнения. Вместо этого используйте pmax и pmin, чтобы получить (поэлементно) верхнюю и нижнюю границы для интервала воздействия для каждого наблюдения, а также для обработки случая, когда возраст на входе и выходе полностью выходит за интервал.

pyears01.smm <- function(ageent, ageleave)
pmax(0, pmin(ageleave, 1) - pmax(ageent, 0))
0 голосов
/ 28 октября 2011

Проблема, которую вы пытаетесь решить, уже рассмотрена в двух известных мне пакетах: «выживание» и «эпи».Вы (без необходимости) заново изобретаете диаграмму Lexis.

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