I am trying to create a function that shows how many “person-years” an individual has contributed to a given age-group in a given period. If the person is alive during the specified interval, the person contributes to the time-interval. For example, for the age-group 0-1, an individual who came under observation at age 0.5 and left at age 3 will have contributed 0.5 years to the person-years for the 0-1 age group.
I’ve been able to run this code successfully over a for-loop, but it takes forever, so I’m trying to implement a vector-based function instead. The function works fine for individual entries, but cannot handle the vectors I pass to it, giving the error: “…the condition has length > 1 and only the first element will be used”
The function I’ve written is as follows:
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}
}
which works fine for evaluating the following:
pyears.smm(0,5)
[1] 1
pyears.smm(0.5,0.75)
[1] 0.25
pyears.smm(2,3)
[1] 0
but does not evaluate NAs correctly:
> pyears.smm(NA,NA)
[1] 0
> pyears.smm("NA",5)
[1] 0
and doesn’t handle vectors correctly:
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
I have read that elseif takes vectors while if statements like this can only evaluate single elements, but I have several layers of nested if statements, so I’m not sure how to fix this. Any suggestions would be appreciated. Thanks!
The vectorised form of an
if–elseconstruct isifelse(not elseif). However, you don’t really need it for this exercise. Instead, usepmaxandpminto get the (elementwise) upper and lower bounds for the exposure interval for each observation, and also to handle the case where the ages at entry and exit are outside the interval entirely.