zoukankan      html  css  js  c++  java
  • 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;

  • 相关阅读:
    Django框架基础之分页
    Django框架基础之session
    Django框架基础之COOKIE
    Django框架基础(二)
    linux挂载/卸载windows共享文件夹
    std::string 字符串操作(分割,去空格)
    Ubuntu sudo不用输入密码的方法
    Qt学习
    ubuntu上利用 checkinstall/dpkg 制作/安装/卸载deb或rpm包
    wxWidgets编译安装
  • 原文地址:https://www.cnblogs.com/SSSR/p/6904636.html
Copyright © 2011-2022 走看看