同时计算多个变量的增长率
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;
我想计算几个变量的增长率而不需要手动计算。有什么聪明的方法吗?
例如请参阅下面 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;