2022年1月23日

〔SAS〕資料處理實例►找出符合條件的日期資料

偶而些朋友和我討論資料處理的問題,有時候只是資料處理流程討論,有時候是程式或語法。我曾透過許多高手的範例而學習到很多,這一次打算把一些有趣的實例,寫成範例,希望對有緣人有幫助(但對點閱率應該沒幫助)。

同一個問題,可以有許多不同的處理流程,本次的方法不見得是最好,也歡迎大家提供不同的流程和語法。

網頁廣告剛好也是你有興趣的,請幫忙點擊廣告,讓我更有動力寫出下一篇文章吧。

以上為模擬的實例(虛擬資料),某個檢測分陰性和陽性的結果,而同一個受測者會在不同的時間接受檢測,時陰時陽。而這次希望解決的問題為:

『受測者曾被檢測出陽性保留最早出現的陽性檢查日期和結果,如只有受測者所有檢查只有陰性結果,則保留最早出現的陰性日期和結果』

因受測者有時陰時陽的狀況,在處理上需要留意,例如個案B在2019/5/3和2020/2/3檢測為陰性,但到2021/1/1則檢測出陽性,我們則需要保留個案B於2021/1/1的檢測資料。

處理流程:

1.找出有陽性的個案ID

2.垂直合併陰性和陽性的所有資料

3.將合併的資料依ID和日期遞增排序

4.將有陽性個案但又有陰性結果的資料刪除(這也可以反向處理)

5.保留每個ID最早日期的資料(最後一步)

程式:

0.先匯入兩份資料吧:

data Negative_0;/*當陰性吧*/
    input id $ date outcome;
    informat date yymmdd10.;
    format date yymmdd10.;
    datalines;
        A 2019/1/1 0
        A 2020/1/1 1
        A 2021/1/1 5
        B 2019/5/3 0
        B 2020/10/6 0
        D 2020/2/3 0
;

data Positive_0;/*陽性好了*/
    input id $ date outcome;
    informat date yymmdd10.;
    format date yymmdd10.;
    datalines;
        B 2021/1/1 20
        B 2021/10/15 30
        C 2019/3/1 40
        D 2019/5/30 50
        D 2021/8/13 60
;

1.找出有陽性的個案ID

proc sort data=Positive_0 out=Positive_idlist (keep=id) nodupkey;
    by id;
run;

2.垂直合併陰性和陽性的所有資料

data Combine_1;
    set     Negative_0 (in=a)
             Positive_0 (in=b)
    ;
            if a=1 then type="Negative";
    else  if b=1 then type="Positive";
run;

3.將合併的資料依ID和日期遞增排序

proc sort data=Combine_1 out=Combine_2;
    by id date;
run;

4.將有陽性個案但又有陰性結果的資料刪除(這也可以反向處理)

data Combine_3;
    merge  Combine_2 (in=a)
                Positive_idlist (in=b drop=tmp);
    by id;
    if b=1 and type="Negative" then del_index=1;
run;

5.保留每個ID最早日期的資料

data Combine_4;
    set  Combine_3 (where=(missing(del_index)=1));
    by id;
    if first.id then output;
    drop del_index;
run;


上面的程式是以Data Step為主的語法,同流程可改以SQL語法,不過流程有稍微調整。

1.找出有陽性的個案ID

proc sql;
    create table SQL_Positive_idlist as
    select distinct id
    from Positive_0
    order by id
    ;
quit;

2.在陰性資料中,先排除有陽性的受測者ID

proc sql;
    create table SQL_Negative_1 as
    select a.*
    from Negative_0 as a left join SQL_Positive_idlist as b on a.id=b.id
    where b.id is null
    ;
quit;

3.垂直合併以排除步驟2的陰性資料,和加入陽性資料

proc sql;
    create table SQL_Combine_1 as
    select *
    from SQL_Negative_1
    Outer Union CORR
    select *
    from Positive_0
    ;
quit;

4.找出每個ID最小日期的資料(也就是最早一筆)

proc sql;
    create table SQL_Combine_2 as
    select distinct *
    from SQL_Combine_1
    group by id
    having  min(date)=date
    ;
quit;

兩個方法都可以試試看喔。

沒有留言:

張貼留言