SAS中文论坛

 找回密码
 立即注册

扫一扫,访问微社区

查看: 2704|回复: 12
打印 上一主题 下一主题

练手系列4:连续值计数

[复制链接]

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
楼主
 楼主| 发表于 2008-7-11 15:21:01 | 只看该作者

练手系列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]
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
沙发
 楼主| 发表于 2008-7-11 17:42:53 | 只看该作者

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]
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
板凳
 楼主| 发表于 2008-7-11 18:33:36 | 只看该作者

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)就不可以了。
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
地板
 楼主| 发表于 2008-7-12 09:32:54 | 只看该作者

to xgghxkhuang

答案倒是没错,是描述写错了,修改了一下,谢谢提醒。 <!-- s:D --><img src="{SMILIES_PATH}/icon_biggrin.gif" alt=":D" title="Very Happy" /><!-- s:D -->

lag的确有你说的问题。这是个好问题,希望大家都注意一下。关于这个问题,在SAS HELP里也有解释。
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
5#
 楼主| 发表于 2008-7-12 21:16:40 | 只看该作者

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]
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
6#
 楼主| 发表于 2008-7-13 13:45:53 | 只看该作者

Re: 练手系列4:连续值计数

写的很简练的,写得很好的,而且写的符合版主的原意。 <!-- s:D --><img src="{SMILIES_PATH}/icon_biggrin.gif" alt=":D" title="Very Happy" /><!-- s:D -->
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
7#
 楼主| 发表于 2008-7-13 15:52:05 | 只看该作者

to byes

这基本就是标准程序了,这么强的程序应该晚些帖上来。让更多的新手有机会多练习。哈哈哈,赞! <!-- s:D --><img src="{SMILIES_PATH}/icon_biggrin.gif" alt=":D" title="Very Happy" /><!-- s:D -->

还有一种做法可以先转置,然后对'01010101010101'类似的字符串做操作来实现,不过这种方法需要两步,效率上还是一步data step好。只是希望大家能有机会多练习,所以提供新的思路。
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
8#
 楼主| 发表于 2008-7-30 11:27:13 | 只看该作者

Re: to byes

学习了!有个问题,data step里使用的first. or last.标签之前不需要对相应变量先排序的么?谢谢!
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
9#
 楼主| 发表于 2008-7-30 15:14:05 | 只看该作者

Re: 练手系列4:连续值计数

需要,如果数据集已经排序就可以直接用。
回复 支持 反对

使用道具 举报

49

主题

76

帖子

1462

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1462
10#
 楼主| 发表于 2008-9-5 22:07:14 | 只看该作者

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;

版主,如果我写得还行就表扬下我吧,我想了~~两天~~才想出来的,不好意思,新手又比较笨。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|手机版|Archiver|SAS中文论坛  

GMT+8, 2026-2-4 23:44 , Processed in 0.068537 second(s), 19 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表