同时计算多个变量的增长率



我想在不手动操作的情况下计算几个变量的增长率。有什么聪明的方法可以做到这一点吗?

例如,请参阅下表sashelp.citiyr

,如下所示:
DATE    PAN     PAN17   PAN18   PANF    PANM
1980    227757  172456  138358  116869  110888
1981    230138  175017  140618  118074  112064
1982    232520  177346  142740  119275  113245
1983    234799  179480  144591  120414  114385
1984    237001  181514  146257  121507  115494
1985    239279  183583  147759  122631  116648
1986    241625  185766  149149  123795  117830
1987    243942  187988  150542  124945  118997
1988    246307  189867  152113  126118  120189
1989    248762  191570  153695  127317  121445

我可以按如下方式创建变量的增长率(例如第一列PAN(,但我想要一种方法来计算所有变量(或我想要的变量,想象一个有几十个变量的情况(。

data test; 
set sashelp.citiyr; 
by date;
Pan_growth = PAN / lag(PAN);
run;

知道如何让它更聪明吗?

转置数据集并使用 BY 组处理。

*transpose to a long format;
proc transpose data=have out=long (rename=col1=Value);
by date;
var pan--panm;
run;
*sort for each variable to be consistent;
proc sort data=long;
by _name_ date;
run;
*calculate lag;
data want;
set long;
by _name_;
prev_val = lag(value);

if not(first._name_) then growth = value/prev_value - 1;
run;

您可以使用宏。此外,为了避免收到警告,您需要一些条件逻辑来防止第一行的除法

data test; 
set sashelp.citiyr; 
by date;
%macro growth(var);
before=lag(&var);
if _N_>1 then &var._growth = &var. / before;
drop before;
%mend;
%growth(PAN);
%growth(PAN17);
%growth(PAN18);
%growth(PANF);
%growth(PANM);
run;

使用数组。

data test;
set sashelp.citiyr;
array vars[*]   pan pan17 pan18 panf panm;
array growth[*] pan_growth pan17_growth pan18_growth panf_growth panm_growth;
do i = 1 to dim(vars);
growth[i] = vars[i]/lag(vars[i]);
end;
run;

如果变量都以某个前缀开头、以序列号结尾或始终以完全相同的顺序结束,则可以使用变量列表快捷方式节省更多时间。

如果您遇到更复杂的情况,即有数百个顺序不正确或没有简单模式的变量,则可以生成所需的名称并使用 SQL 和dictionary.columns将它们保存到宏列表中。只需确保从查询中排除任何不相关的变量即可。

proc sql noprint;
select name
, cats(name, '_growth')
into :vars separated by ' '
, :growth_vars separated by ' '
from dictionary.columns
where     libname = 'SASHELP'
AND memname = 'CITIYR'
AND upcase(name) NE 'DATE'
;
quit;
data test2;
set sashelp.citiyr;
array vars[*]   &vars.;
array growth[*] &growth_vars.;
do i = 1 to dim(vars);
growth[i] = vars[i]/lag(vars[i]);
end;
run;

最新更新