Başka ifadeler R içinde vektör girdilerini doğru olarak değerlendirmiyorsa, kullanıcı tanımlı fonksiyonumun iç içe geçmiş olması - lütfen yardım edin

Bir bireyin belirli bir yaştaki belirli bir yaş grubuna ne kadar "insan-yılı" kattığını gösteren bir fonksiyon yaratmaya çalışıyorum. Kişi belirtilen aralıkta yaşıyorsa, kişi zaman aralığına katkıda bulunur. Örneğin, 0-1 yaş grubu için, 0,5 yaş grubunda gözlem altında olan ve 3 yaşında bırakılan bir birey, 0-1 yaş grubu için kişi-yıllara 0,5 yıl katkıda bulunacaktır.

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"

Yazdığım işlev şöyledir:

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} 
}

Aşağıdakileri değerlendirmek için iyi çalışıyor:

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

ancak NA'ları doğru olarak değerlendirmez:

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

ve vektörleri doğru şekilde işlemez:

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

Bu gibi ifadeler sadece tek öğeleri değerlendirebiliyorsa, ancak ifadeler içeriyorsa birkaç katman katmanım varsa, bu vektörleri aldığını okumuştum, bu yüzden bunu nasıl düzelteceğimi bilmiyorum. Herhangi bir öneri takdir edilecektir. Teşekkürler!

0

3 cevap

Aldığınız uyarı mesajı, özellikle başka bir programlama dilinden geliyorsanız, yaygındır. Vektörlerde çalışan ifelse() işlevini arıyorsunuz. Uyarı mesajı size söylendiğinde, sadece ilk koşulu değerlendirdi. İşte kodunuzun ifelse() sürümü:

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
katma
Çok teşekkürler! Bu işe yaradı - ifelse içinde iç içe geçme biçimine rastlamamıştım ama sorun buydu.
katma yazar SMM, kaynak

- else yapısının vectorized formu ifelse (elseifif değil) şeklindedir. Ancak, bu alıştırma için gerçekten buna ihtiyacınız yok. Bunun yerine, her gözlem için pozlama aralığı için (eleman yönünde) üst ve alt sınırlar elde etmek için pmax ve pmin komutlarını kullanın ve aynı zamanda girişteki yaşların bulunduğu durumu da ele alın. çıkış tamamen aralık dışındadır.

pyears01.smm <- function(ageent, ageleave)
pmax(0, pmin(ageleave, 1) - pmax(ageent, 0))
2
katma
Teşekkür ederim - bu tür şeyler için çok yararlı.
katma yazar SMM, kaynak

Çözmeye çalıştığınız sorun, şu anda bildiğim iki paket halinde ele alındı: "hayatta kalma" ve "epi". Lexis diyagramını yeniden yaratıyorsunuz (gereksiz yere).

0
katma