mysql窗口函数同比环比_sas使用proc report实现同比 环比 占比。顺带实现了sql的窗口函数...

使用sas实现同比 环比 占比,其中环比和占比是使用proc report实现的,环比使用data步实现,但是其中每年的总计是使用proc report来实现的。

proc report 可以实现proc print proc tabluate proc sort proc means 以及data步的一些功能,所以有中想法,把proc report当做是进行复杂统计的实现方法之一,比如sql中的开窗函数就可以用proc report实现。

以下是具体的代码和数据。

转载请注明出处:http://www.cnblogs.com/SSSR/p/6904636.html

代码参考自:Using PROC REPORT To Produce Tables With Cumulative Totals and Row Differences

更新--20170525 20:10

总结:report的compute步中是先一列一列的计算,新增列的时候可以用前面列的数据,跟在data步中新建列感觉区别不大,可以使用data步中的函数。

最后的BREAK AFTER year / SUMMARIZE SKIP OL UL ;这里只能是summarize求和,不能是其他的。

想着测试一下data步中的lag函数在report的compute中是否可以使用,没想到呀!居然可以直接求出来同比,大赞,记录下。

DATA quarter;

DO year=97 TO 99;

DO j=1 TO 12;

IF j=1 THEN xx='1dec1997'd;

QUARTER=QTR( intnx('month',xx,J) );

DO n=1 to 100;

sales=int(normal(123)*(20)+quarter*7);

IF QUARTER=3 THEN SALES=SALES-15;

OUTPUT;

END;

END;

END;

RUN;

PROC FORMAT ;

VALUE PCTA

.='(na)'

OTHER=[PERCENT8.0];

VALUE DOLLARA

.='(na)'

OTHER=[DOLLAR8.0];

RUN;

ods html file='c:/myhtml.htm';

PROC REPORT DATA=QUARTER NOWD OUT=Six

SPLIT="*" CENTER HEADSKIP HEADLINE;

COLUMN

( year quarter )

( sales=salessum pct)

(diff diff_pct pct_tongbi) ;

DEFINE year / GROUP;

DEFINE quarter / GROUP FORMAT=8. CENTER;

DEFINE salessum / ANALYSIS sum FORMAT=DOLLAR8. SUM ;

DEFINE pct / computed FORMAT=PERCENT8.0 ;

DEFINE diff / COMPUTED FORMAT= DOLLAR8.0 ;

DEFINE diff_pct / COMPUTED FORMAT=percent9.0;

define pct_tongbi/computed format=percent9.0;

COMPUTE BEFORE year ;*modify;

r=0;

last=0;

total=salessum;

ENDCOMP;

COMPUTE pct;/*实现了sql的窗口函数*/

pct=salessum/total;

ENDCOMP;

COMPUTE diff ;

r+1;

IF r=1 THEN diff=. ;

else DO;

if _BREAK_ EQ " " THEN

diff=salessum-last ;

else diff = . ;

end;

last = salessum;

ENDCOMP;

COMPUTE diff_pct ;

diff_pct= (diff/(last-diff) );

ENDCOMP;

COMPUTE pct_tongbi;/*计算同比,可以直接使用lag函数,so data步中的很多函数估计就都可以在report中使用了!*/

pct_tongbi=salessum/lag6(salessum)-1;

ENDCOMP;

BREAK AFTER year / SUMMARIZE SKIP OL UL ;

RUN;

ods html close;

以下代码比较复杂,计算同比使用了data步。

DATA quarter;

DO year=97 TO 99;

DO j=1 TO 12;

IF j=1 THEN xx='1dec1997'd;

QUARTER=QTR( intnx('month',xx,J) );

DO n=1 to 100;

sales=int(normal(123)*(20)+quarter*7);

IF QUARTER=3 THEN SALES=SALES-15;

OUTPUT;

END;

END;

END;

RUN;

PROC FORMAT ;

VALUE PCTA

.='(na)'

OTHER=[PERCENT8.0];

VALUE DOLLARA

.='(na)'

OTHER=[DOLLAR8.0];

RUN;

/*这个是实现占比和环比的,生成了一个数据集,all也在这里生成了*/

ods html file='c:/myhtml.htm';

PROC REPORT DATA=QUARTER NOWD OUT=Six

SPLIT="*" CENTER HEADSKIP HEADLINE;

COLUMN

( year quarter )

( sales=salessum pct)

(diff diff_pct) ;

DEFINE year / GROUP;

DEFINE quarter / GROUP FORMAT=8. CENTER;

DEFINE salessum / ANALYSIS sum FORMAT=DOLLAR8. SUM ;

DEFINE pct / computed FORMAT=PERCENT8.0 ;

DEFINE diff / COMPUTED FORMAT= DOLLAR8.0 ;

DEFINE diff_pct / COMPUTED FORMAT=percent9.0;

COMPUTE BEFORE year ;*modify;

r=0;

last=0;

total=salessum;

ENDCOMP;

COMPUTE pct;

pct=salessum/total;

ENDCOMP;

COMPUTE diff ;

r+1;

IF r=1 THEN diff=. ;

else DO;

if _BREAK_ EQ " " THEN

diff=salessum-last ;

else diff = . ;

end;

last = salessum;

ENDCOMP;

COMPUTE diff_pct ;

diff_pct= (diff/(last-diff) );

ENDCOMP;

*BREAK AFTER year / SUMMARIZE SKIP OL UL ;

RUN;

ods html close;

/*对report中生成的数据集进行进一步的加工*/

DATA sixout(keep=year quarterx salessum pct diff_pct);

retain year quarterx salessum pct diff_pct ;

set six;

if quarter=. then quarterx='ALL';

else quarterx=quarter;

if not missing(_break_) then pct=1;

RUN;

/*排序,为下一步求同比做准备*/

proc sort data=sixout out=sixout;

by year quarterx;

run;

/*求同比直接用lag5函数即可,这个大家都知道,*/

/*但是有时候我们会遇到今年和去年的分类数据不同,必去去年一季度有数据,但是今年为0,就不现实了,所以这个时候我们还需要先将所有的分类(季度)数据和年份进行全匹配,缺失的填充为0,然后再进行处理*/

data sixx_result;

set sixout;

*lag5=lag5(salessum);

tongbi=salessum/lag5(salessum)-1;

format tongbi PERCENT8.2 ;

format pct PERCENT8.2 ;

format diff_pct PERCENT8.2 ;

run;


版权声明:本文为weixin_42134769原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。