我的用户定义函数带有嵌套的 if else 语句无法正确评估 R 中的矢量输入 - 请帮助



我正在尝试创建一个函数,该函数显示在给定时间段内个人为给定年龄组贡献了多少"人-年"。如果这个人在指定的时间间隔内活着,那么这个人对时间间隔有贡献。例如,对于0-1岁年龄组,在0.5岁时接受观察并在3岁时离开的个体将对0-1岁年龄组的人年贡献0.5年。

我已经能够在for循环中成功运行此代码,但它需要永远,所以我试图实现一个基于向量的函数。该函数可以很好地处理单个条目,但不能处理我传递给它的向量,给出错误:"…条件长度> 1,并且只使用第一个元素"

我写的函数如下:

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

但不能正确评估NAs:

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

和不能正确处理vector:

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语句只能评估单个元素,但我有几层嵌套的if语句,所以我不知道如何解决这个问题。任何建议都将不胜感激。谢谢!

您得到的警告消息是常见的,特别是如果您使用的是另一种编程语言。你在寻找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

如果你在谷歌上搜索if elseifelse()之间的差异,我相信你会找到一些好东西。这里有一个上升到顶部的链接:http://rwiki.sciviews.org/doku.php?id=tips:programming:ifelse

if - else构造的矢量化形式是ifelse(不是elseif)。然而,在这个练习中并不需要它。相反,使用pmaxpmin来获得每个观测值的暴露间隔的(元素上的)上限和下限,并且还可以处理进入和退出时的年龄完全超出间隔的情况。

pyears01.smm <- function(ageent, ageleave)
pmax(0, pmin(ageleave, 1) - pmax(ageent, 0))

您试图解决的问题已经在我所知道的两个包中得到了解决:"survival"one_answers"epi"。您正在(不必要地)重新创建Lexis图。

最新更新