楼主: funwin
5778 20

[求助]如何增加观测值? [推广有奖]

11
pobel 在职认证  发表于 2009-1-6 11:42:00

The result:

Obs    name    item           date    money

  1    AAA     salary       200712     5000
  2    AAA     bonus        200712     2000
  3    AAA     allowance    200712     1000
  4    AAA     salary       200801     5000
  5    AAA     bonus        200801     2000
  6    AAA     allowance    200801     1000
  7    AAA     salary       200802     5000
  8    AAA     bonus        200802     2000
  9    AAA     allowance    200802     1000
 10    AAA     salary       200803     5400
 11    AAA     salary       200804     5400
 12    AAA     salary       200805     5400
 13    AAA     salary       200806     5500
 14    BBB     salary       200710     3500
 15    BBB     bonus        200710     3600
 16    BBB     salary       200711     3500
 17    BBB     bonus        200711     3600
 18    BBB     salary       200712     3500
 19    BBB     bonus        200712     3600
 20    BBB     salary       200801     3500
 21    BBB     bonus        200801     3600
 22    BBB     salary       200802     3500
 23    BBB     bonus        200802     3600
 24    BBB     salary       200803     3500
 25    BBB     bonus        200803     3600
 26    BBB     salary       200804     6100

和谐拯救危机

12
myxixi 发表于 2009-1-6 11:50:00

不错,学些了

13
zhitler 发表于 2009-1-6 16:36:00
以下是引用pobel在2009-1-6 11:37:00的发言:

data origin;
     length item $10;
     input name $ date : yymmn6. item $ money;
     cards;
AAA 200712 salary 5000
AAA 200712 bonus 2000
AAA 200712 allowance 1000
AAA 200803 salary 5400
AAA 200806 salary 5500
BBB 200710 salary 3500
BBB 200710 bonus 3600
BBB 200804 salary 6100
;

proc sort data=origin;
     by name descending date;
run;

data result;
     set origin;
     by name descending date;
     nextdate=lag(date);
     if first.name then nextdate=.;
     if date and nextdate then datedif=datdif(date,nextdate,'30/360');
     retain dif;
     if first.date then dif=datedif;
     if dif then i=dif/30;
     if dif le 1 or dif=. then output;
     else do j=0 to i-1;
             date=date+30;
             output;
          end;
     format date yymmn6.;
     keep name date item money;
run;

proc sort data=result;
     by name date;
run;

很好,很强大

14
funwin 发表于 2009-1-6 19:44:00

太强了!要好好学学消化一下了!

此处果然卧虎藏龙!

非常感谢楼上各位的帮助支持!!!

15
funwin 发表于 2009-1-7 02:26:00
以下是引用pobel在2009-1-6 11:37:00的发言:

data origin;
     length item $10;
     input name $ date : yymmn6. item $ money;
     cards;
AAA 200712 salary 5000
AAA 200712 bonus 2000
AAA 200712 allowance 1000
AAA 200803 salary 5400
AAA 200806 salary 5500
BBB 200710 salary 3500
BBB 200710 bonus 3600
BBB 200804 salary 6100
;

proc sort data=origin;
     by name descending date;
run;

data result;
     set origin;
     by name descending date;
     nextdate=lag(date);
     if first.name then nextdate=.;
     if date and nextdate then datedif=datdif(date,nextdate,'30/360');
     retain dif;
     if first.date then dif=datedif;
     if dif then i=dif/30;
     if dif le 1 or dif=. then output;
     else do j=0 to i-1;
             date=date+30;
             output;
          end;
     format date yymmn6.;
     keep name date item money;
run;

proc sort data=result;
     by name date;
run;

出现这种情况:

如果下一个月按前一个月加30天来得出,可能出现1月后面是3月,缺少了2月。

比如198912后面是199001,但再后面就出现了199003。

如果把上面的AAA的第一个日期改为198912,就会发现没有199002了;

是否与一开始把日期 input date yymmn6.有关?因为我要输入的日期其实是每个月的月末,但如果用format date yymmddn8. 可以发现其实输入了月初。

望高手解答一下!

16
funwin 发表于 2009-1-7 02:42:00

关键不在月初 月末,主要还在于30/360这个假设。

如果是闰年,比如1990,2月只有28天,1月31,加30天就过了2月,到了3月1,再加30天,是3月31,还在3月。所以出现没有2月却有两个3月的情况!

这个问题如何解决??

17
pobel 在职认证  发表于 2009-1-7 10:10:00

data origin;
     length item $10;
     input name $ year 5-8 month 9-10 item $ money;
     monnum=year*12+month;
     cards;
AAA 198912 salary 5000
AAA 198912 bonus 2000
AAA 198912 allowance 1000
AAA 200803 salary 5400
AAA 200806 salary 5500
BBB 200710 salary 3500
BBB 200710 bonus 3600
BBB 200804 salary 6100
;

proc sort data=origin;
     by name descending monnum;
run;

data result;
     set origin;
     by name descending monnum;
     nextmon=lag(monnum);
     if first.name then nextmon=.;
     if monnum and nextmon then dif=nextmon-monnum;
     retain dif1;
     if first.monnum then dif1=dif;
     if dif1 le 1 or dif1=. then output;
     else do i=0 to dif1-1;
             monnum1=monnum+i;

            year=int(monnum1/12);
            month=monnum1-year*12;
            mod=mod(monnum1,12);
            if mod=0 then do;
                             year=year-1;
                             month=12;
                         end;
                           output;
     end;
          keep name item year month money;

run;


data result1;
     set result;
     yearchar=trim(left(year));
     monchar=trim(left(month));
     if length(monchar)=1 then monchar="0"||monchar;
     yymm=trim(yearchar)||monchar;
     date=input(yymm,yymmn6.);
     format date yymmn6.;
     keep date name item money;
run;

proc sort data=result1;
     by name date;
run;

和谐拯救危机

18
myxixi 发表于 2009-1-7 10:55:00

牛人好多

19
sushe1527 发表于 2009-1-7 11:57:00
好强大

20
funwin 发表于 2009-1-7 23:11:00
以下是引用pobel在2009-1-7 10:10:00的发言:

data origin;
     length item $10;
     input name $ year 5-8 month 9-10 item $ money;
     monnum=year*12+month;
     cards;
AAA 198912 salary 5000
AAA 198912 bonus 2000
AAA 198912 allowance 1000
AAA 200803 salary 5400
AAA 200806 salary 5500
BBB 200710 salary 3500
BBB 200710 bonus 3600
BBB 200804 salary 6100
;

proc sort data=origin;
     by name descending monnum;
run;

data result;
     set origin;
     by name descending monnum;
     nextmon=lag(monnum);
     if first.name then nextmon=.;
     if monnum and nextmon then dif=nextmon-monnum;
     retain dif1;
     if first.monnum then dif1=dif;
     if dif1 le 1 or dif1=. then output;
     else do i=0 to dif1-1;
             monnum1=monnum+i;

            year=int(monnum1/12);
            month=monnum1-year*12;
            mod=mod(monnum1,12);
            if mod=0 then do;
                             year=year-1;
                             month=12;
                         end;
                           output;
     end;
          keep name item year month money;

run;


data result1;
     set result;
     yearchar=trim(left(year));
     monchar=trim(left(month));
     if length(monchar)=1 then monchar="0"||monchar;
     yymm=trim(yearchar)||monchar;
     date=input(yymm,yymmn6.);
     format date yymmn6.;
     keep date name item money;
run;

proc sort data=result1;
     by name date;
run;

Perfect!

Pobel, thanks so much!

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

本版微信群
加好友,备注cda
拉您进交流群
GMT+8, 2025-12-20 15:20