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
[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)<=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)<30 then x=1;
end;
end;
y+x;
x=0;
if eof then output;
keep y;
run;
包括两种的话可以的,不包括就没辙了。。