作者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/cn.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