SAS中文论坛

标题: 请教问题: SAS 编程 [打印本页]

作者: shiyiming    时间: 2011-3-4 11:26
标题: 请教问题: SAS 编程
有一个困扰我多时的问题:

问: 在30天内,有多少病人服用了超过2种药物?SAS数据中的变量有:病人ID, 用药日期以及对应的药名。

id        date            medicine
1        2010jan01          a
1        2010jan04          a
1        2010jan16          a
1        2010feb04            b
2        2010mar03           c
2        2010mar04           c
....

假设数据量很大,有30万行

敬请牛人指教如何用SAS实现,并且计算机用时越少越好。
作者: shiyiming    时间: 2011-3-5 01:20
标题: Re: 请教问题: SAS 编程
So far, no one solve my problem. I am wondering if I describe the problem clearly, or my problem is so easy that no one care about it?

Please help me and thanks millions!

^_^
作者: shiyiming    时间: 2011-3-5 11:09
标题: Re: 请教问题: SAS 编程
可以用sas的自我匹配技术,不知道是不是你要的
proc sql;
        create table one as
        select  id, drug, min(date) as startdate
     from raw
         group by id, drug
;quit;

proc sql;
        create table output as
     select  distinct id as patient,  'Y' as indicator 'Patient who had more than 2 drugs in 30 day'
      from one as a , one as b
      where a.id = b.id
                        and (a.startdate - b.startdate)  le 30
;quit;
作者: shiyiming    时间: 2011-3-5 13:04
标题: Re: 请教问题: SAS 编程
看不太懂这句 (a.startdate - b.startdate) le 30,我先琢磨琢磨自我匹配技术。 非常感谢高人的解决方法!

^_^
作者: shiyiming    时间: 2011-3-5 16:39
标题: Re: 请教问题: SAS 编程
hash或者double set

如果楼主给出一段可以试的伪数据(楼主的日期是非标格式,并且数据太少),我可以试一试。
作者: shiyiming    时间: 2011-3-5 22:43
标题: Re: 请教问题: SAS 编程
[quote:4qsiueqo]楼主的日期是非标格式,[/quote:4qsiueqo]

可以用ANYDTDTE.informat来读。
我曾经问过猪头类似的程序。
我感觉这个问题不是很容易。得出30天内不同药的名字和个数不是很难。可是标定出每个药的日期有些麻烦。
我的思路是:
这个问题可以看成是每种药物的开始日期即为date,而假定的结束日期为date+30.而30内用的药即为每个小阶段里存在的药物。
作者: shiyiming    时间: 2011-3-5 23:50
标题: Re: 请教问题: SAS 编程
楼主,这个行吗 ?

[code:w6une77r]data raw;
input id date $10. drug $1.;
date=input(catt(substr(date,8,2), substr(date,5,3),substr(date,1,4)), date12.);
cards;
1 2010jan01 a
1 2010jan04 a
1 2010jan16 a
1 2010feb04 b
1 2010feb17 a
1 2010mar08 c
2 2010feb10 c
2 2010feb14 c
2 2010mar03 b
2 2010mar04 c
3 2010jan16 a
3 2010jan18 a
3 2010mar04 c
;
run;
proc sort  data=raw out=ex;
   by id  date drug;
run;

data ex;
   set ex;
   if id=lag(id) and   0 <= date-lag(date)< 30 and drug ne lag(drug);
run;
proc sql;
   select id as patient, 'Y' as indicator 'Patient who had more than 2 drugs in 30 day'
          from ex;
quit;        [/code:w6une77r]
作者: shiyiming    时间: 2011-3-6 00:06
标题: Re: 请教问题: SAS 编程
@sxlion
个人感觉仅用 date-lag(date) 可能会不严谨吧
数据太少,不好测试...
作者: shiyiming    时间: 2011-3-6 08:55
标题: Re: 请教问题: SAS 编程
考虑过lag的局限,不过对于楼主这个问题好像OK。

楼主要是说3个的话,就有点麻烦了,两个的话就投机点的想到了这个,不知道有没bug,楼主试试才知道。

ps: 后面的sql 加一点。
[code:3ngn1xxz]proc sql;
   select distinct  id as patient, 'Y' as indicator 'Patient who had more than 2 drugs in 30 day'
          from ex
          group by id;
quit;[/code:3ngn1xxz]
作者: shiyiming    时间: 2011-3-6 09:49
标题: Re: 请教问题: SAS 编程
这个程序真是很好。
lag 在这里应该没有问题。因为这根本不是条件性地执行lag。对于记录的每一行,lag都例行执行一次。
不过说实在的,如果问题只是想知道某个人是否在30天吃过至少两种药的话,那么这个程序也没有什么难度可言。我以为他需要重合的具体的药的名称,用药时间等等。另外,如果只是30万的记录,讲程序的效率也就没有什么大的意思。其实,对于常规的过程,运行30万次,对于sas来说也不过是几分钟(或者十几分钟)而已。
作者: shiyiming    时间: 2011-3-7 14:52
标题: Re: 请教问题: SAS 编程
感觉就是sql的自连,然后数一下不同药的个数,限制一下30天的移动窗口......
作者: shiyiming    时间: 2011-3-10 15:44
标题: Re: 请教问题: SAS 编程
既然是你困扰很长时间的问题,大家回答你问题,你理所当然要客气些,而且,起码要有反馈的信息和效率信息。

[code:3ugybnoj]data raw(keep=coun);
attrib id1 format=best8. date1 format=date. drug1 format=$1.;
retain id1;
retain date1;
retain drug1;
retain count;
input #1 id date $10. drug $1. ;
input #2 id2 date2 $10. drug2 $1. ;
date=input(catt(substr(date,8,2), substr(date,5,3),substr(date,1,4)), date12.);
date2=input(catt(substr(date2,8,2), substr(date2,5,3),substr(date2,1,4)), date12.);
if (id=id2 and drug^=drug2 and date2<date+30) then do;if count^=id then coun+1;count=id;end;
if id1^=. and (id1=id and drug1^=drug and date<date1+30) then do;if count^=id then coun+1;count=id;end;
id1=id2;
date1=date2;
drug1=drug2;
cards;
1 2010jan01 a
1 2010jan04 a
1 2010jan16 a
1 2010feb04 b
1 2010feb17 a
1 2010mar08 c
2 2010feb10 c
2 2010feb14 c
2 2010mar03 b
2 2010mar04 c
3 2010jan16 a
3 2010jan18 a
3 2010mar04 c
;
run;
[/code:3ugybnoj]
作者: shiyiming    时间: 2011-3-10 16:41
标题: Re: 请教问题: SAS 编程
第一次看Super K写代码,大家快来围观啦 !  <!-- s:D --><img src="{SMILIES_PATH}/icon_biggrin.gif" alt=":D" title="Very Happy" /><!-- s:D -->
作者: shiyiming    时间: 2011-3-11 13:35
标题: Re: 请教问题: SAS 编程
我是属于那种问问题,然后问题大部分很难得到满意答案那种~~~
只是偶尔想挑战下。
上面的代码,因为把重点放在了infile和input,则不用建立中间数据集,30万记录0.28秒就够了。 <!-- s:mrgreen: --><img src="{SMILIES_PATH}/icon_mrgreen.gif" alt=":mrgreen:" title="Mr. Green" /><!-- s:mrgreen: -->
不过问问题的问完就走了,这相当让人不痛快。 <!-- s:evil: --><img src="{SMILIES_PATH}/icon_evil.gif" alt=":evil:" title="Evil or Very Mad" /><!-- s:evil: -->
作者: shiyiming    时间: 2011-3-18 22:07
标题: Re: 请教问题: SAS 编程
响应下,留个脚印。Super K是爱问问题的大牛,到哪个论坛都是的。
作者: shiyiming    时间: 2011-3-18 22:22
标题: Re: 请教问题: SAS 编程
跟这里和sasor以及sasl的大牛比,我可是小字辈的  <!-- s:wink: --><img src="{SMILIES_PATH}/icon_wink.gif" alt=":wink:" title="Wink" /><!-- s:wink: -->
作者: shiyiming    时间: 2011-3-18 22:31
标题: Re: 请教问题: SAS 编程
SK就是大牛,比SK更强大的用2只手就能数的过来。 <!-- s:-D --><img src="{SMILIES_PATH}/icon_biggrin.gif" alt=":-D" title="Very Happy" /><!-- s:-D -->
作者: shiyiming    时间: 2011-3-19 00:30
标题: Re: 请教问题: SAS 编程
老施你这样抬举我,我以后在各位大侠面前就不好混了~ <!-- s:lol: --><img src="{SMILIES_PATH}/icon_lol.gif" alt=":lol:" title="Laughing" /><!-- s:lol: --> 而且特容易骄傲~
我还是虚心好好学习的好,况且本来自己有很多东西都不精通,还经常走冤枉路。 <!-- s:) --><img src="{SMILIES_PATH}/icon_smile.gif" alt=":)" title="Smile" /><!-- s:) -->
作者: shiyiming    时间: 2011-3-21 15:55
标题: Re: 请教问题: SAS 编程
很久没来,顶下大牛啊,哈哈
作者: shiyiming    时间: 2011-5-30 01:28
标题: Re: 请教问题: SAS 编程
data raw;
input id drug $ 13 date $ 3-11 ;
date=input(catt(substr(date,8,2), substr(date,5,3),substr(date,1,4)), date12.);
cards;
1 2010jan01 a
1 2010jan04 a
1 2010jan16 a
1 2010feb04 b
1 2010feb17 a
1 2010mar08 c
2 2010feb10 c
2 2010feb14 c
2 2010mar03 b
2 2010mar04 c
3 2010jan16 a
3 2010jan18 a
3 2010mar04 c
;
run;
proc sort data=raw;
by id drug date;
run;
data a;
do n=1 by 1 until (last.id);
do m=1 by 1 until (last.drug);
set raw end=eof;
by id drug notsorted;
if date-lag(date)&lt;=30 then x=1;
end;
end;
y+x;
x=0;
if eof then output;
run;
作者: shiyiming    时间: 2011-5-30 01:55
标题: Re: 请教问题: SAS 编程
不好意思,题目理解错了,
data b;
do n=1 by 1 until (last.id);
set raw end=eof;
by id;
if drug ne lag(drug) then do;
if date-lag(date)&lt;30 then x=1;
end;
end;
y+x;
x=0;
if eof then output;
keep y;
run;
包括两种的话可以的,不包括就没辙了。。




欢迎光临 SAS中文论坛 (http://mysas.net/forum/) Powered by Discuz! X3.2