问题描述
我的桌子就像图片上的第一张桌子一样。
它是有关每天在外汇市场上进行银行交易(购买减去出售)的信息。我想像第二张桌子一样计算累积结果。银行的数目及其名称,以及日期都是不确定的。我是SAS的新手,试图找到解决方案,但没有发现任何有用的东西。我会很高兴为您提供帮助。
解决方法
当这样的数据采用宽格式时,与长格式相比,在SAS中进行处理可能会更加困难。长数据格式具有按组处理,建立索引,过滤等形式的众多优点。围绕此概念设计了许多SAS程序。
有关以下示例的更多信息,请查看SAS's example on the Program Data Vector和by-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;