SAS中文论坛

标题: 练手系列4:连续值计数 [打印本页]

作者: shiyiming    时间: 2008-7-11 15:21
标题: 练手系列4:连续值计数
[code:15l8zu9r]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;[/code:15l8zu9r]
源表解释:userid表示客户号,month表示月份,purchase表示购买量(1有购买,0无购买)。

目标要求:
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&#46;userid then do;max_cons_no_purchase=0;cons_last_month=0;end;
        if first&#46;purchase then cnt=0;
        cnt+1;
        if last&#46;purchase and purchase=0 then do;
                        max_cons_no_purchase =max(max_cons_no_purchase ,cnt);
                        last_month=month;
                        if cnt&gt;=2 then cons_last_month=month;
        end;
        if last&#46;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&gt;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;

版主,如果我写得还行就表扬下我吧,我想了~~两天~~才想出来的,不好意思,新手又比较笨。
作者: shiyiming    时间: 2008-9-5 23:28
标题: Re: 练手系列4:连续值计数
如果是新手能够按照要求完成就很不错了,恭喜进阶!
作者: shiyiming    时间: 2008-9-6 15:08
标题: Re: 练手系列4:连续值计数
谢谢版主! <!-- s:D --><img src="{SMILIES_PATH}/icon_biggrin.gif" alt=":D" title="Very Happy" /><!-- s:D -->
新手,努力中 <!-- s8) --><img src="{SMILIES_PATH}/icon_cool.gif" alt="8)" title="Cool" /><!-- s8) -->
作者: shiyiming    时间: 2008-9-27 10:41
标题: TO: 开心小珠
如果再加几个数据,你的程序就出现计算错误,如
3 10 1
3 11 0
3 12 1
另,请解释一下你的编程思路,以供学习,谢谢。




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