目标要求:
1、每个客户无购买行为的最后一个月份是哪月?
2、每个客户最后一次连续无购买行为的那几个月的最后一个月份是哪月?
3、每个客户无购买行为的最大连续月数。
[color=#FF0000:15l8zu9r][size=150:15l8zu9r]只用1个data step实现全部需求。[/size:15l8zu9r][/color:15l8zu9r]
[quote:15l8zu9r]userid last_month cons_last_month max_cons_no_purchase
1 12 10 4
2 11 8 3[/quote:15l8zu9r]作者: shiyiming 时间: 2008-7-11 17:42 标题: Re: 练手系列4:连续值计数 [code:z7rwar9w]
data output;
set source; by userid;
retain last_month cons_last_month max_cons_no_purchase _t;
if first.userid then do;
last_month=.;
max_cons_no_purchase=0;
cons_last_month=.;
_t=0;
end;
if purchase=1 then _t=0;
if purchase=0 then do;
last_month=month;
_t+1;
end;
if _t>max_cons_no_purchase then do;
max_cons_no_purchase=_t;
cons_last_month=month;
end;
if last.userid then output;
keep userid last_month cons_last_month max_cons_no_purchase;
run;
[/code:z7rwar9w]作者: shiyiming 时间: 2008-7-11 18:33 标题: Re: 练手系列4:连续值计数 data source;
infile datalines;
input userid month purchase;
datalines;
1 1 1
1 2 0
1 3 0
1 4 1
1 5 0
1 6 1
1 7 0
1 8 0
1 9 0
1 10 0
1 11 1
1 12 0
2 1 0
2 2 0
2 3 0
2 4 1
2 5 0
2 6 1
2 7 0
2 8 0
2 9 1
2 10 1
2 11 0
2 12 1
;
run;
data try;retain a1 month1 month2 month3 0;
set source;
by userid;
c=lag(month);
if purchase=0 then a1=a1+1;
if purchase=1 then a1=0;b=lag(a1);
if purchase=0 then month1=month;
if purchase=1 then month1=month1+0;
if dif(purchase)=1 then do;
if month3<b then do;
month3=b;month2=c;
end;
end;
if first.userid then do;
if purchase=0 then a1=1;
if purchase=1 then a1=0;
month3=0;month2=0;
end;
if last.userid then do;
last_month=month1 ;
if a1>month3 then do;
cons_last_month=12;
max_cons_no_purchase=a1;
end;
if a1<=month3 then do;
cons_last_month=month2;
max_cons_no_purchase=month3;;
end;
end;
keep userid last_month cons_last_month max_cons_no_purchase;
if last_month=. then delete;
run;
我写的比较笨 <!-- s:D --><img src="{SMILIES_PATH}/icon_biggrin.gif" alt=":D" title="Very Happy" /><!-- s:D -->,版主答案好像列错了。
提问我写的如果不用中间变量c=lag(month)直接用lag(month)就不可以了。作者: shiyiming 时间: 2008-7-12 09:32 标题: to xgghxkhuang 答案倒是没错,是描述写错了,修改了一下,谢谢提醒。 <!-- s:D --><img src="{SMILIES_PATH}/icon_biggrin.gif" alt=":D" title="Very Happy" /><!-- s:D -->
lag的确有你说的问题。这是个好问题,希望大家都注意一下。关于这个问题,在SAS HELP里也有解释。作者: shiyiming 时间: 2008-7-12 21:16 标题: Re: 练手系列4:连续值计数 [code:35dtmlay]
data result(keep=userid cons_last_month last_month max_cons_no_purchase);
retain userid cons_last_month last_month max_cons_no_purchase;
set source;
by userid purchase notsorted;
if first.userid then do;max_cons_no_purchase=0;cons_last_month=0;end;
if first.purchase then cnt=0;
cnt+1;
if last.purchase and purchase=0 then do;
max_cons_no_purchase =max(max_cons_no_purchase ,cnt);
last_month=month;
if cnt>=2 then cons_last_month=month;
end;
if last.userid;
run;
[/code:35dtmlay]作者: shiyiming 时间: 2008-7-13 13:45 标题: Re: 练手系列4:连续值计数 写的很简练的,写得很好的,而且写的符合版主的原意。 <!-- s:D --><img src="{SMILIES_PATH}/icon_biggrin.gif" alt=":D" title="Very Happy" /><!-- s:D -->作者: shiyiming 时间: 2008-7-13 15:52 标题: to byes 这基本就是标准程序了,这么强的程序应该晚些帖上来。让更多的新手有机会多练习。哈哈哈,赞! <!-- s:D --><img src="{SMILIES_PATH}/icon_biggrin.gif" alt=":D" title="Very Happy" /><!-- s:D -->
还有一种做法可以先转置,然后对'01010101010101'类似的字符串做操作来实现,不过这种方法需要两步,效率上还是一步data step好。只是希望大家能有机会多练习,所以提供新的思路。作者: shiyiming 时间: 2008-7-30 11:27 标题: Re: to byes 学习了!有个问题,data step里使用的first. or last.标签之前不需要对相应变量先排序的么?谢谢!作者: shiyiming 时间: 2008-7-30 15:14 标题: Re: 练手系列4:连续值计数 需要,如果数据集已经排序就可以直接用。作者: shiyiming 时间: 2008-9-5 22:07 标题: Re: 练手系列4:连续值计数 版主,帮看看我的程序吧。
data result;
retain userid last_month cons_last_month max_cons_no_purchase;
set source;
by userid;
if first.userid then do;max_cons_no_purchase=0;count=0;end;
if purchase=0 then do;last_month=month;count+1;end;else count=0;
if count>1 then do;cons_last_month=month;max_cons_no_purchase=max(max_cons_no_purchase,count);end;
if last.userid;
drop month purchase count;
run;