ネストされたif elseステートメントを使用した私のユーザー定義関数は、Rのベクトル入力を正しく評価していません - 助けてください

私は、一定期間に与えられた年齢層に個人がどれだけ貢献したかを示す関数を作成しようとしています。指定された間隔で人が生きている場合、その人はその時間間隔に貢献します。例えば、年齢層0-1については、0.5歳で観察され、3歳で放置された個人は、0歳から1歳までの年齢に対して0.5歳に貢献する。

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"

私が書いた関数は次のとおりです:

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文があるので、これを修正する方法がわかりません。任意の提案をいただければ幸いです。ありがとう!

0

3 答え

あなたが得ている警告メッセージは、特に別のプログラミング言語から来ている場合には、共通のものです。ベクトルで動作する 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 you Google or search on SO for differences between if else and ifelse(), I'm sure you'll find some good stuff. Here's one link that rose to the top: http://rwiki.sciviews.org/doku.php?id=tips:programming:ifelse

3
追加された
どうもありがとう!これはうまくいきました - 私はifelseの中に入れ子にするためのフォーマットに遭遇しませんでしたが、それが問題であると考えました。
追加された 著者 SMM,

else 構成の ifelse (elseifはありません)のベクトル化形式です。しかし、あなたは本当にこの運動のためにそれを必要としません。代わりに、 pmaxpmin を使用して、各観測の露出間隔の上限と下限を取得します。出口はその区間の外側にあります。

pyears01.smm <- function(ageent, ageleave)
pmax(0, pmin(ageleave, 1) - pmax(ageent, 0))
2
追加された
ありがとう - このタイプのものに非常に役立ちます。
追加された 著者 SMM,

あなたが解決しようとしている問題は、私が知っている2つのパッケージ、「生存」と「エピ」ですでに取り上げられています。あなたは(不必要に)レクシスの図を改革しています。

0
追加された