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

Calculate growth rates for several variables at the same time

我想计算几个变量的增长率而不需要手动计算。有什么聪明的方法吗?

例如请参阅下面 sashelp.citiyr 中的 table,看起来像:

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;

知道如何让它更智能吗?

使用数组。

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;

如果您的变量都以特定前缀开头,以连续数字结尾,或者始终以完全相同的顺序排列,则使用 variable list shortcuts.

可以节省更多时间

如果您遇到更复杂的情况,其中有数百个变量顺序不正确或没有简单模式,您可以生成所需的名称并使用 [=20= 将它们保存到宏列表中] 和 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;

转置您的数据集并使用 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;