若想將整個欄位的資料移動到下一格,可使用函數LAG(),若想直接計算上下兩筆資料間的數值差,可使用函數DIF(),請參考以下的示範:

利用以下程式建立一個資料檔aa, 若想計算前後兩次門診的時間間隔,可直接利用dif(opd_date)計算兩次門診的時間差,若想將門診日期向下移動,可利用lag(opd_date)

[程式一]
data aa;
        input opd_date yymmdd10.;/*-門診日期-*/
                 lag_date=lag(opd_date);
                 dif_day=dif(opd_date);
                 format opd_date lag_date yymmdd10.;
cards;
1998-01-03
1998-02-02
1998-02-16
1998-03-16
;
proc print;
run;

[結果一]

INF()  

 

以上介紹了如何將整個欄位的資料移動到下一格,或計算上下兩筆資料間的數值差,使用了LAG()DIF(),但是如果資料有MISSING且資料來自不同人,程式將如何改寫?

利用以下程式建立一個資料檔aa, 檔案中有A,B兩個病人的資料,其中A有一筆門診資料是MISSING的。若想計算前後兩次門診的時間間隔,若直接利用dif(opd_date)計算兩次門診的時間差,或利用lag(opd_date)將門診日期向下移動將造成邏輯上的錯誤。([程式二])

本日將介紹函數: IFN()
IFN(logical-expression, value-returned-when-true, value-returned-when-false <,value-returned-when-missing>)

[程式二]

data aa;
        input id $ opd_date yymmdd10.;/*-門診日期-*/

        lag_date=lag(opd_date);
        format opd_date lag_date yymmdd10.;
cards;
A 1998-01-03
A 1998-02-02
A 
A 1998-03-16
A 1998-03-23
B 2001-05-12
B 2001-11-14
B 2001-12-12
;
proc print;
run;

以下程式以每一個病人的ID作為判斷依據, IFN()中先限定依ID找到每一個人的第一筆資料,再將資料向下移動或與下一筆相減,當遇到門診日期MISSING則直接往下移動或與下一筆相減。

[程式三]
data bb;
        set aa;
             by ID;
             lag_date2= ifn( first.ID , (.) , lag(opd_date) );
             dif_day2=ifn( first.ID , (.) , dif(opd_date) );
             format opd_date lag_date2 yymmdd10.;
proc print;
run;

 

[結果二]

 

lag_date是直接將opd_date(門診日期)向下移動,而未考慮門診日期是來自不同人的資料。lag_date2則是考慮不同人的資料後,再將opd_date向下移動。因此id='A'的患者〞之opd_date若以LAG()向下移動,則第6筆日期差欄位(dif_day)則由id='B'的第1opd_dateid='A'的第5opd_date相減,因此產生錯誤。

所以,要選擇ifn(),再將lag()包覆進去,限定每人的起始資料,以及限定遇到missing跳過。

 

INF()-2  

 如果在分析健保資料庫時,個人的身份必需同時考慮ID, birthday,程式可以修改如下。

 
[程式四]
data bb;
        set aa;
             by ID birthday;
                  lag_date2= ifn( first.ID=1 & first.birthday=1 | first.ID=0 & first.birthday=1, (.) , lag(opd_date) );
                  dif_day2=ifn(  first.ID=1 & first.birthday=1 | first.ID=0 & first.birthday=1 , (.) , dif(opd_date) );
                  format opd_date lag_date2 yymmdd10.;
proc print;
run;

因為我國戶政中可能出現相同ID,卻不同人的情況,此時要將生日考慮進來,因此資料移動時的依據包括ID與生日,當ID相同時取第一筆,同時,在相同的ID下,生日也要取第一筆;若相同的ID,但生日是第一次出現,但是,是在其他筆第一次出現,表示為相同ID但不同生日的人。當定位了第一筆資料後,就可將資料往下移動一格,若想移動2格以上,或向上移動,需要利用SASexpand程序,將以另外的專章討論。

 

文章標籤
創作者介紹
創作者 estat 的頭像
estat

blog.estat.com.tw

estat 發表在 痞客邦 留言(3) 人氣()


留言列表 (3)

發表留言
  • 訪客
  • 您好,想詢問一下
    如果是要以後筆的入院日期減去前筆的出院日期的話
    要算30日內再住院
    語法應該要怎麼寫呢??
  • estat
  • /*利用以下的例子建立入出院資料,若想知道前一次出院至下一次入院是否相隔30天以上,必須計算上一次入院與下一次出院的天數差,因此必須將入院日期向上移動一列,SAS中沒有LAG()的相反函數,因此可藉由PROC EXPAND來執行。*/

    data aa;
    input id $ in_date yymmdd10. +1 out_date yymmdd10.;/*-入出院日期-*/
    format in_date out_date yymmdd10.;
    cards;
    A 1998-01-03 1998-02-14
    A 1998-05-02 1998-05-16
    A 1999-03-16 1999-04-18
    B 2001-05-12 2001-05-22
    B 2004-03-20 2004-05-21
    ;
    proc print;
    run;

    proc expand data=aa out=bb method = none;
    by id;
    convert in_date = in_date_lead / transformout=(lead); /*將入院日期向上移動一列*/
    run;

    data cc;
    set bb;
    day_dif=in_date_lead-out_date; /*前一次出院至下一次入院相隔天數*/
    run;
  • 訪客
  • 您好,
    請問如果要看同一ID某診斷在90天內至少出現兩次,
    應如何使用lag來完成,謝謝!!!