I would like to calculate the growth rate of several variables without doing it manually. Is there any smart way to do it?
E.g. See table below from sashelp.citiyr
that looks like:
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
I can create the growth rate of the variables as follows (example for first column PAN
) but I would like a way to compute it for all the variables (or those I want, imagine a case with dozens of them).
data test;
set sashelp.citiyr;
by date;
Pan_growth = PAN / lag(PAN);
run;
Any idea how to make this smarter?
Use arrays.
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;
If your variables all start with a certain prefix, end in sequential numbers, or are always in the exact same order, you can save even more time by using variable list shortcuts.
If you have an even more complex case where you have hundreds of variables that aren't in the right order or have no simple pattern, you can generate the desired names and save them into macro lists using SQL and dictionary.columns
. Just make sure you exclude any irrelevant variables from your query.
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;