用累积值创建表

时间:2020-08-12 14:57:55

标签: sas datastep

我的桌子就像图片上的第一张桌子一样。 enter image description here

它是有关每天在外汇市场上进行银行交易(购买减去出售)的信息。我想像第二张桌子一样计算累积结果。银行的数目及其名称,以及日期都是不确定的。我是SAS的新手,试图找到解决方案,但没有发现任何有用的东西。我会很高兴为您提供帮助。

1 个答案:

答案 0 :(得分:2)

当这样的数据采用宽格式时,与长格式相比,在SAS中进行处理可能会更加困难。长数据格式具有按组处理,建立索引,过滤等形式的众多优点。围绕此概念设计了许多SAS程序。

有关以下示例的更多信息,请查看SAS's example on the Program Data Vectorby-group processing。掌握这些概念将有助于您进行data step编程。

有两种解决方法:

1。使用sum statement和按组处理。

在此示例中,我们将:

  • 将数据从宽到长转换为银行名称为字符变量
  • 对每个银行进行累计金额
  • 再次转换回长距离

通过将银行名称转换为字符变量,我们可以对其进行按组处理。

/* Convert from wide to long */
proc transpose data=raw 
               out=raw_transposed 
               name=bank
               ;
    by date;
run;

proc sort data=raw_transposed;
    by bank date;
run;

/* Use by-group processing to get cumulative values by month for each bank */
data cumulative_long;
    set raw_transposed;
    by bank date;

    /* Reset the cumulative sum for each bank */
    if(first.bank) then call missing(cumulative);

    cumulative+COL1;
run;

proc sort data=raw_transposed;
    by date bank;
run;

/* Convert from long to wide */
proc transpose data=raw_transposed
               out=want(drop=_NAME_)
               ;
    by date;
    id bank;
    var COL1;
run;

sum语句可用作以下代码的快捷方式:

data cumulative_long;
    set raw_transposed;
    by bank date;
    retain cumulative;

    if(first.bank) then cumulative = 0;

    cumulative = cumulative + COL1;
run;

cumulative在数据集中不存在:我们在这里创建它。每当SAS继续读取新行时,此值将丢失。我们希望SAS传递最后的价值。 retain告诉SAS向前传送其最后一个值,直到我们更改它为止。

2。使用宏变量和字典表

第二种选择是从字典表中读取所有银行名称,以防止转置。我们将:

  • 使用PROC SQL将特殊表dictionary.columns中的库名称读入宏变量中
  • 使用数组执行累计和

这假定银行命名方案始终以“ Bank”为前缀。如果不遵循常规模式,则可以从初始SQL查询中排除所有其他变量。

proc sql noprint;
    select name
         , cats(name, '_cume')
    into :banks separated by ' '
       , :banks_cume separated by ' '
    from dictionary.columns
    where     memname = 'RAW'
          AND libname = 'WORK'
          AND upcase(name) LIKE 'BANK%'
    ;
quit;

data want;
    set raw;

    array banks[*]      &banks.;
    array banks_cume[*] &banks_cume.;

    do i = 1 to dim(banks);
        banks_cume[i]+banks[i];
    end;

    drop i;
run;