2015-09-22 59 views
1

我的數據的格式爲:使用SAS或SQL查找行內的第一個和最後一個非空值?目前

ID  Fill1   Fill2   Fill3   Fill4   Fill5  
1  01JAN2014  28JAN2014  26FEB2014  .    . 
2  .    05FEB2012  03MAR2012  02APR2012  01MAY2012 
3  10MAR2015  08APR2015  07MAY2015  05JUN2015  03JUL2015 
4  .    .    20FEB2013  18MAR2013  .   

而且我想每個ID創建處理「情節」。換句話說,對於每個ID我想找到第一個和最後一個非空填充,然後計算兩個日期之間的差異。例如,對於ID = 1,我需要查找01JAN2014和26FEB2014之間的時間差。也就是說,

Fill1 - Fill3 = episodeduration

但ID = 4,我需要找到,

Fill3 - Fill4 = episodeduration

其中episodeduration是創造了一個新的變量。我有超過30k的唯一ID,具有不同的「第一」和「最後」填充日期。在此先感謝您的幫助。

+0

你有沒有試圖自己解決這個問題?如果是這樣,你有什麼嘗試?本網站不旨在提供按需代碼服務。 – user667489

+1

查看最小/最大功能 – Reeza

+0

@ user667489我很清楚本網站的目標是什麼。您好像對我的許多帖子都有負面反應,而99%的人對我的問題很滿意並且很滿意。也就是說,我不覺得有義務回答你提出的輕度冒犯性問題。天兒真好。 – Justin

回答

1
data have; 
input Id Fill1 date9. Fill2 date9. Fill3 date9. Fill4 date9. Fill5 date9.; 
format Fill1 - Fill5 date9.; 
cards; 
1 01JAN201428JAN201426FEB2014 
2   05FEB201203MAR201202APR201201MAY2012 
3 10MAR201508APR201507MAY201505JUN201503JUL2015 
4     20FEB201318MAR2013 
; 
run; 

data want; 
set have; 
    array fill {5}; 
    format first last date9.; 

    do i = 1 to dim(fill); 
     first=coalesce(first, fill(i)); 
     last=coalesce(fill(i), last); 
    end; 

    episodeduration = last - first; 

    drop i; 
run; 

使用array聲明通過變量和coalesce()函數來創建數組和循環來查找第一個/最後一個非缺失。

評論:此代碼將從第一個變量到最後一個變量找到第一個/最後一個。如果你需要在日期方面的第一/最後,最小和最大功能是好的:min(of fill1 -- fill5); - 無需循環。

+0

hi @vasja非常感謝你,這是我一直在尋找的確切邏輯。你的例子工作完美,但是當我去我的數據集上運行這個相同的代碼時,我得到了輸出中無處不在的值(fill1,fill2,... first,last,episodeduration。在我的實際數據集中,「ID」不是1,2,3而是一個很長的患者標識符,例如00023432.難道這是原因嗎? – Justin

+0

出現在日誌中的唯一注意事項是:「由於對缺失值執行操作而生成缺失值,每個位置由((行):(列))中的(次數)給出。 – Justin

+0

你的意思是在數據上運行第二步數據?確保你的變量正好是fill1,fill2 ... fill5,它們是數字。如果它們是字符,最好先將它們轉換爲SAS日期數字。 – vasja

1

vasja的SAS版本看起來相當不錯,這裏是它如何完成SQL方面(這幾乎完全相同的過程)。

Select *, 
    DATEDIFF(day, 
     CONVERT(date,COALESCE(date1, date2, date3, date4, date5)), 
     CONVERT(date, COALESCE(date5,date4,date3,date2,date1)) 
    ) 
from SomeTableNameAboutEpisodes; 

基本上,您使用COALESCE找到第一個非空值,並且可以將其轉換成一個日期。然後,您將採用兩個日期之間的差異。但是,這隻適用於空單元格沒有值(空)並且沒有空行的情況。 (你可以簡單地把一個ISNULL(DATEDIF(...),0)雖然)。

+0

非常感謝,作爲一個SQL選擇,這非常有用。我很欣賞它。 – Justin

0

您可以使用遞減的「SAS變量列表」(FILL5-FILL1)使其更容易一些。

data diff; 
    set have; 
    first = coalesce(of fill1-fill5); 
    i  = whichn(first,of fill1-fill5); 
    last = coalesce(of fill5-fill1); 
    j  = 6-whichn(last, of fill5-fill1); 
    format first last date9.; 
    run; 

Obs Id  Fill1  Fill2  Fill3  Fill4  Fill5  first i   last j 

1  1 01JAN2014 28JAN2014 26FEB2014   .   . 01JAN2014 1 26FEB2014 3 
2  2   . 05FEB2012 03MAR2012 02APR2012 01MAY2012 05FEB2012 2 01MAY2012 5 
3  3 10MAR2015 08APR2015 07MAY2015 05JUN2015 03JUL2015 10MAR2015 1 03JUL2015 5 
4  4   .   . 20FEB2013 18MAR2013   . 20FEB2013 3 18MAR2013 4 
相關問題