SAS中文论坛

标题: 求助:根据一个表的信息产生新表(规则比较复杂) [打印本页]

作者: shiyiming    时间: 2009-8-24 18:09
标题: 求助:根据一个表的信息产生新表(规则比较复杂)
data a;
input Date yymmdd8. ID$ Num;
format Date yymmdd10.;
cards;
09-07-08 001 100
09-07-08 002 50
09-07-09 001 30
09-07-10 004 10
09-07-13 003 60
09-07-14 002 50
09-07-15 004 30
;
run;

现在需要产生一个新的数据(如下),变量名为上述数据的ID号,新数据的第一列为时间(不包括周末),其他数据的产生规则(以第2列为例):7月8号购买了100个001,因此第1行第2列为100,但是这100只能连续存在5次(不是5天,因为日期不连续),即第6行第2列需要减100;7月9号又购买了30个001,因此第2行第2列为100+30=130;第3-5行第2列都为130;第一行购买的100个001只能连续存在5天,第6行第2列需要减100,为30;第2行列购买的30个001只能连续存在5天,第7行第2列需要减30,变为0;第8-11行第2列都为0;

         001   002   003   004
08-07-08   100    50      0      0
08-07-09   130    50      0      0
08-07-10   130    50      0     10
08-07-13   130    50     60     0
08-07-14   130    100   60     0
08-07-15   30      50     60    40
08-07-16    0       50     60    40
08-07-17    0       50     60    30
08-07-20    0       50      0     30
08-07-21    0        0       0     30
08-07-22    0        0       0      0
作者: shiyiming    时间: 2009-8-24 21:12
标题: Re: 求助:根据一个表的信息产生新表(规则比较复杂)
有3个问题不明白:
1、08年7月11日、12日、18日、19日是周五和周六,可规则中写的是“不包括周末”
2、id为004的记录在你给的结果数据中不符合规则,原始数据中004第一次出现是7月10日,结果数据中是7月9日,且并未连续出现5次
3、原始数据最后一条数据是7月15日的,连续5次应该截止到7月21日(不含18、19日),结果数据中包含一条7月22日的记录(变量值为0)
[code:1jqiuzjx]data a;
        input Date yymmdd8. ID $ Num;
        format Date yymmdd10.;
cards;
08-07-08 001 100
08-07-08 002 50
08-07-09 001 30
08-07-10 004 10
08-07-13 003 60
08-07-14 002 50
08-07-15 004 30
;

data b;
        set a;
        num_001=0;
        num_002=0;
        num_003=0;
        num_004=0;
        select(id);
                when('001') num_001=num;       
                when('002') num_002=num;       
                when('003') num_003=num;       
                when('004') num_004=num;       
        end;
        output;
        do i=1 to 6;
                date+1;
                if weekday(date) not in (6,7) then output;
        end;
        keep date num_:;
run;

proc sort data=b;
        by date;
run;

data b;
        retain date _001 _002 _003 _004;
        call missing(_001,_002,_003,_004);
        do _n_=1 by 1 until(last.date);
                set b;
                by date;
                _001+num_001;
                _002+num_002;
                _003+num_003;
                _004+num_004;
        end;
        keep date _001 _002 _003 _004;
run;[/code:1jqiuzjx]
作者: shiyiming    时间: 2009-8-24 21:39
标题: Re: 求助:根据一个表的信息产生新表(规则比较复杂)
谢谢hopewell:D  <!-- s:D --><img src="{SMILIES_PATH}/icon_biggrin.gif" alt=":D" title="Very Happy" /><!-- s:D --> 刚刚都改了一下:1.应该是09年,2、3都是你说的那样,我开始的结果有点问题~

不过有个问题是,如果我的ID取值很多(比如有10000个),你这个程序能稍微改改变得简单点么?如果更复杂一点,如果每个数据连续出现的不是5次,而是100次,在时间足够长的情况下,产生的b表就会很长了~
作者: shiyiming    时间: 2009-8-25 01:18
标题: Re: 求助:根据一个表的信息产生新表(规则比较复杂)
解决了多ID和连续大于5次的问题,没有数据测试,不知道效率怎么样
[code:1mvsc132]
/* NOTE&#58; 原始数据的日期连续且不包含周末 */
data a;
   input Date yymmdd8&#46; ID $ Num;
   format Date yymmdd10&#46;;
cards;
08-07-08 001 100
08-07-08 002 50
08-07-09 001 30
08-07-10 004 10
08-07-13 003 60
08-07-14 002 50
08-07-15 004 30
;

%macro repeat_lag(in_ds,out_ds,lag);
        options nosymbolgen nomprint;
        %local id_num id_list_num id_list_sum;
        /* 获取变量列表 */
        %macro get_id_list;
                proc contents data=&amp;out_ds out=_temp(keep=name varnum) noprint nodetails;
                run;
                proc sort data=_temp;
                        by varnum;
                run;
                data _null_;
                        set _temp(firstobs=2) end=eof;
                        length id_list $256;
                        retain id_list;
                        id_list=catx(' ',id_list,name);
                        if eof then do;
                                call symput('id_num',put(_n_,best8&#46;));
                                call symput('id_list_num',id_list);
                                call symput('id_list_sum',translate(id_list,'sum','num'));
                        end;
                run;
        %mend;
        /* 转置原始数据 */
        proc transpose data=&amp;in_ds out=&amp;out_ds(drop=_name_) prefix=num_;
                by date;
                id id;
                var num;
        run;
        %get_id_list
        /* 在结束日对冲数据 */
        data &amp;out_ds(drop=i);
                set &amp;out_ds;
                output;
                date=intnx('weekday',date,&amp;lag,'sameday');
                array arr{*} num_&#58;;
                do i=1 to dim(arr);
                        if arr(i) ne &#46; then arr(i)=-arr(i);
                end;
                output;
        run;
        /* 整理数据 */
        proc sort data=&amp;out_ds;
                by date;
        run;
        data &amp;out_ds(keep=date sum_&#58;);
                do _n_=1 by 1 until(last&#46;date);
                        set &amp;out_ds;
                        by date;
                        array arr_num{*} &amp;id_list_num;
                        array arr_sum{*} &amp;id_list_sum (&amp;id_num*0);
                        do i=1 to &amp;id_num;
                                arr_sum(i)=sum(arr_sum(i),arr_num(i));
                        end;
                end;
        run;
        proc datasets library=work nolist;
                delete _temp;
        run;
        quit;
%mend;

%repeat_lag(a,b,5)[/code:1mvsc132]
作者: shiyiming    时间: 2009-8-25 09:51
标题: Re: 求助:根据一个表的信息产生新表(规则比较复杂)
运行出来的结果不对呢,我看了半天也没看出问题出在哪里 <!-- s:( --><img src="{SMILIES_PATH}/icon_sad.gif" alt=":(" title="Sad" /><!-- s:( -->  <!-- s:( --><img src="{SMILIES_PATH}/icon_sad.gif" alt=":(" title="Sad" /><!-- s:( -->
作者: shiyiming    时间: 2009-8-25 10:26
标题: Re: 求助:根据一个表的信息产生新表(规则比较复杂)
用你给的数运行出来的结果对呀,我也看了半天没看出问题出在哪里 <!-- s:( --><img src="{SMILIES_PATH}/icon_sad.gif" alt=":(" title="Sad" /><!-- s:( -->  <!-- s:( --><img src="{SMILIES_PATH}/icon_sad.gif" alt=":(" title="Sad" /><!-- s:( -->  <!-- s:( --><img src="{SMILIES_PATH}/icon_sad.gif" alt=":(" title="Sad" /><!-- s:( -->
作者: shiyiming    时间: 2009-8-25 11:41
标题: Re: 求助:根据一个表的信息产生新表(规则比较复杂)
奇怪了,
我最后得到得表b如下:
Date        sum_001        sum_002        sum_004        sum_003
.        -130        -100        -40        -60
2008-7-8        -30        -50        -40        -60
2008-7-9        0        -50        -40        -60
2008-7-10        0        -50        -30        -60
2008-7-13        0        -50        -30        0
2008-7-14        0        0        -30        0
2008-7-15        0        0        0        0
作者: shiyiming    时间: 2009-8-25 13:22
标题: Re: 求助:根据一个表的信息产生新表(规则比较复杂)
我让一朋友在他机器上跑了一遍,没什么问题呀,不知道什么原因




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