作者west1996 ()
看板Statistics
標題Re: [程式] SAS選擇最近的值後轉置
時間Sat Mar 26 01:49:45 2016
注意:沒有data可以測,憑想像空打,程式碼可能有錯,請自行debug一下
這支macro可以一次轉一個變數一個時間點,餵給他三個東西
1. 資料集名稱
2. 變數名稱
3. 月數(要給一個數字)
macro會產生該名稱該變數的結果在work裡,程式碼最後一行的範例是把yourdata這個
資料集的GOT變數的3個月資訊轉出來存成work.out_GOT_3M
P.S.要一次轉多個變數多個時間點需要另外加工包裝macro,比較麻煩,既然你的欄位
不多,時間點也不多,data也不大,所以乾脆多跑幾次macro再自行merge
資料就好,速度上不會差很多
程式碼如下:
%macro aggregatedata(dsn=, var=, month=);
data work.out_&var._&month.M;
set &dsn.;
by id;
retain temp_value temp_month over_value over_month over_flag;
length &var._&month.M $ 12;
if first.id=1 then do; temp_value=.; temp_month=.; over_value=.; over_month=.; over_flag=0; end;
if &month.-1<= month <= &month.+1 and &var. ^= . and temp_month ^= &month. and over_flag ^= 1 then do;
if month <= &month. then do;
temp_value=&var.;
temp_month=month;
end;
else if month> &month. then do;
over_value=&var.;
over_month=month;
over_flag=1;
end;
end;
if last.id=1 then do;
if temp_value = . and over_value= . then &var._&month.M='.';
else if temp_value=. and over_value ^=. then &var._&month.M=cats(over_value,'(',over_month,')');
else if temp_month = &month. then &var._&month.M=cats(temp_value,'(',temp_month,')');
else if &month.-temp_month <= over_month-&month. then &var._&month.M=cats(temp_value,'(',temp_month,')');
else if &month.-temp_month > over_month-&month. then &var._&month.M=cats(over_value,'(',over_month,')');
end;
output;
end;
keep id &var._&month.M;
run;
%mend;
%aggregatedata(dsn=yourdata, var=GOT, month=3)
※ 引述《yonny (悠逆)》之銘言:
: [軟體程式類別]: SAS (R也可以 但是我跟R比較不熟)
: [程式問題]: 資料處理
: [軟體熟悉度]:熟悉
: [問題敘述]:
: 我的資料大概長像這樣
: No是每次檢驗的流水號 ID相同是同一個人
: GOT和GPT是在不同時間點做的檢驗數值
: 但不是每個時間點 都有兩個檢查都做
: 而且不同人做檢查的時間點也都不相同
: No ID Month GOT GPT
: 1 1 0.2 41 34
: 2 1 2.8 42 .
: 3 1 3.5 43 36
: 4 1 3.7 44 37
: 5 1 4.9 45 38
: 6 1 5.5 51 39
: 7 1 5.7 52 40
: 8 1 6.0 53 .
: 9 1 6.2 54 .
: 10 2 0.9 20 21
: 11 2 4.0 22 .
: 12 2 4.1 24 25
: 13 2 5.7 . 36
: 14 2 6.0 30 .
: 以下是我期望的資料型態
: ID GOT_0M GOT_3M GOT_6M GPT_0M GPT_3M GPT_6M
: 1 41(0.2) 42(2.8) 53(6.0) 34(0.2) 36(3.5) 40(5.7)
: 2 20(0.9) 22(4.0) 30(6.0) 21(0.9) . 36(5.7)
: 我想要把資料轉置成橫的,以GOT為例,
: 我要創造三個變項 GOT_0M GOT_3M GOT_6M (分別為0,3,6個月的GOT)
: 這三個時間點若無完全符合的值, 則抓正負一個月內的值來代替
: 若正負一個月內都無值, 則missing
: 值後面括號(是用哪個時間點的值)
: ---
: 以上大概是我的資料型態
: 實際的資料 有好幾百人的資料
: 每個人大概都有30~100個檢驗的時間點
: 檢驗數值(如GOT,GPT之類的) 大概有10幾個
: 而我們要取的時間點實際上也不只有三個(0,3,6,12,18,24,36,48M)
: 感覺有點複雜(囧)
: 我目前大概查一下 可能用PROC SQL先寫出來
: 再看改成MACRO
: (我今天掙扎了一下午 只寫了一點點簡單的 完全離目標很遠XD)
: 想請問看板上的高手有無建議要用什麼statement寫比較適合?
: 我再研究一下
: 或是若有高手可以幫忙寫出來
: 小小3000P表達感謝!
: 非常謝謝!!
--
※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 220.136.120.240
※ 文章網址: https://webptt.com/m.aspx?n=bbs/Statistics/M.1458928188.A.1CC.html
1F:推 yonny: 我試過大概沒問題了(倒數第二個end是多的) 非常謝謝!! 03/26 11:03
2F:→ yonny: 其實我實際資料欄位*時間點 可能會有100多個 哈哈 03/26 11:05
3F:→ yonny: 不過或許可以用MACRO+do loop合併看看 03/26 11:06
4F:→ yonny: 我自己是用PROC SQL寫 可以同時轉多個時間點和變項 03/26 11:06
5F:→ yonny: 只是寫法比較耗資源 或許資料大一點 時間要比較多 03/26 11:07
6F:→ yonny: 差最後一些小地方還沒完成 之後寫完再跟您分享 03/26 11:09
7F:→ yonny: 非常感謝你!!!!!! 03/26 11:09
8F:→ west1996: 100多個對我來說算是小拉,因為ctrl+C, ctrl+V一下就結 03/26 21:06
9F:→ west1996: 束了,要包成可以處理多個時間點多個變數難其實不是難 03/26 21:07
10F:→ west1996: 在寫程式,而是需要規範input的變數清單與時間點清單的 03/26 21:07
11F:→ west1996: 撰寫格式,這需要溝通,所以我當初才沒包這一段,否則 03/26 21:08
12F:→ west1996: 包成那個版本其實比較有利,因為無論多大的資料量都只需 03/26 21:09
13F:→ west1996: 要掃過一遍資料就處理完了~ 03/26 21:09
14F:推 yonny: 謝謝你啦! 下面我也有回我的作法 給您參考~ 03/26 22:51