Could I use if-then statement in the proc expand as follows?
%macro all16;
%local j_list k_list j k j_index k_index;
%let j_list = 3 6 9 12;
%let k_list =3 3 3 3;
%do j_index=1 %to 4;
%let j = %scan(&j_list, &j_index);
%do k_index=1 %to 4;
%let k = %scan(&k_list, &k_index);
data vickyhave;
input date :yymmdd10. gdp country;
format date yymmdds10.;
cards;
19800131 28 222
19800229 29.375 222
19800331 27.125 222
19800430 24.25 222
19800530 26.75 222
19800630 30.75 222
19800731 37.75 222
19800829 40.75 222
19800930 43.375 222
19801031 51.5 222
19801128 56 222
19801231 24.5 222
19810130 22.25 222
19810227 20 222
19810331 22.75 222
19810430 20.5 222
19810529 19.5 222
19810630 18 222
19810731 18.5 222
19810831 17.5 222
19810930 14.25 222
19811030 14.375 222
19811130 15.75 222
19811231 14.625 222
19820129 14.625 222
19820226 12.875 222
19820331 12.625 222
19820430 12.625 222
19820528 12 222
19820630 12.125 222
19820730 10.875 222
19820831 11.375 222
19820930 11.75 222
19821029 14.25 222
19821130 13.75 222
19821231 13 222
19830131 14.25 222
19830228 13.5 222
19830331 14 222
19830429 14.625 222
19830531 14.5 222
19830630 15.75 222
19830729 15.375 222
19830831 14.625 222
19830930 16.625 222
19831031 15 222
19831130 15 222
19831230 15.5 222
19840131 15.375 222
19840229 14 222
19840330 13.625 222
19840430 12.125 222
19840531 11.625 222
19840629 11.5 222
19840731 10.125 222
19840831 11.875 222
19840928 12.125 222
19841031 12.25 222
19841130 11.5 222
19841231 11.125 222
19850131 13.5 222
19850228 14.875 222
19850329 14.25 222
19850430 13.625 222
19850531 13.25 222
19850628 13.375 222
19850731 13.75 222
19850830 12.75 222
19850930 12.25 222
19851031 11.25 222
19851129 12 222
19851231 12.75 222
19860131 13.125 222
19860228 14 222
19860331 14.5 222
19860430 13.25 222
19860530 13.875 222
19860630 13.5 222
19860731 11.875 222
19860829 12.25 222
19860930 11.25 222
19861031 13.25 222
19861128 13 222
19861231 13.125 222
19870130 17 222
19870227 17 222
19870331 16 222
19870430 15.25 222
19870529 19.5 222
19870630 20.25 222
19870731 22 222
19870831 22 222
19870930 21.625 222
19871030 13.125 222
19871130 10.875 222
19871231 13.75 222
19880129 14.5 222
19880229 14.75 222
19880331 13.125 222
19880429 12 222
19880531 13.375 222
19880630 16.625 222
19880729 15.5 222
19880831 15.875 222
19880930 15.25 222
19881031 14.375 222
19881130 13.375 222
19881230 14.5 222
19890131 16.125 222
19890228 16.625 222
19890331 17 222
19890428 18.25 222
19890531 20 222
19890630 18.625 222
19890731 21 222
19890831 21.25 222
19890929 20 222
19891031 17.375 222
19891130 19.875 222
19891229 20.75 222
19800131 25.75 257
19800229 25.625 257
19800331 20.375 257
19800430 20.5 257
19800530 20.75 257
19800630 22 257
19800731 21.625 257
19800829 22.875 257
19800930 24.375 257
19801031 24.5 257
19801128 24.5 257
19801231 22.875 257
19810130 23.75 257
19810227 24.875 257
19810331 28.5 257
19810430 27.75 257
19810529 27.5 257
19810630 27.125 257
19810731 29.5 257
19810831 26.875 257
19810930 27.5 257
19811030 26.75 257
19811130 25.75 257
19811231 23.25 257
19820129 23.5 257
19820226 22.375 257
19820331 22.625 257
19820430 22.125 257
19820528 23.125 257
19820630 22.75 257
19820730 20.5 257
19820831 23.5 257
19820930 24.25 257
19821029 27.75 257
19821130 31 257
19821231 30 257
19830131 31.25 257
19830228 30.875 257
19830331 33.75 257
19830429 32.875 257
19830531 34.375 257
19830630 36.25 257
;
run;
proc expand data= vickyhave
out=vickywant (where=((gdp>=max_gdp_hist&j) and (centered_window_range=2*&J+1)))
method=none ;
by country;
id date;
convert gdp=max_gdp_hist&j / transformin=(lag 1) transformout=(nomiss movmax &j);
convert gdp=centered_window_range / transformin=(*0 +1 cmovsum 2*&J+1 ) ;
if j=3 then convert gdp=gmean_future_rate_3 / transformin=(ratio 1 log cmovave ( 0 0 0 0 1 1 0) exp -1);
else if j=6 then convert gdp=gmean_future_rate_3 / transformin=(ratio 1 log cmovave ( 0 0 0 0 0 0 0 1 1 0) exp -1);
else if j=9 then convert gdp=gmean_future_rate_3 / transformin=(ratio 1 log cmovave ( 0 0 0 0 0 0 0 0 0 0 1 1 0) exp -1);
else convert gdp=gmean_future_rate_3 / transformin=(ratio 1 log cmovave ( 0 0 0 0 0 0 0 0 0 0 1 1 0) exp -1);
run;
%end;
%end;
%mend all16;
%all16;
But it looks to me you want your macro to generate dynamic code, so the proc expand would look like that:
proc expand
data= vickyhave
out=vickywant (
where=((gdp>=max_gdp_hist&j) and (centered_window_range=2*&J+1))
)
method=none
;
by country;
id date;
convert gdp=max_gdp_hist&j / transformin=(lag 1) transformout=(nomiss movmax &j);
convert gdp=centered_window_range / transformin=(*0 +1 cmovsum 2*&J+1 );
%if &j=3 %then %do;
convert gdp=gmean_future_rate_3 / transformin=(ratio 1 log cmovave ( 0 0 0 0 1 1 0) exp -1);
%end;
%else %if &j=6 %then %do;
convert gdp=gmean_future_rate_3 / transformin=(ratio 1 log cmovave ( 0 0 0 0 0 0 0 1 1 0) exp -1);
%end;
%else %if &j=9 %then %do;
convert gdp=gmean_future_rate_3 / transformin=(ratio 1 log cmovave ( 0 0 0 0 0 0 0 0 0 0 1 1 0) exp -1);
%end;
%else %do;
convert gdp=gmean_future_rate_3 / transformin=(ratio 1 log cmovave ( 0 0 0 0 0 0 0 0 0 0 1 1 0) exp -1);
%end;
run;
Since the only thing that changes is the parameter string in the brackets, you could create that with
data _null_;
length parmstr $50;
do i = 1 to &j;
parmstr = catx(' ',parmstr,put(i,best.));
end;
parmstr = trim(parmstr) !! ' 0 1 1 0';
call symput('parmstr',trim(parmstr));
run;
and so avoid the %if by having a single convert statement with &parmstr.
Maxim 1: read the documentation: http://support.sas.com/documentation/cdl/en/etsug/60372/HTML/default/viewer.htm#etsug_expand_sect013...
The EXPAND procedure supports a BY, CONVERT and ID statement, that's it.
But it looks to me you want your macro to generate dynamic code, so the proc expand would look like that:
proc expand
data= vickyhave
out=vickywant (
where=((gdp>=max_gdp_hist&j) and (centered_window_range=2*&J+1))
)
method=none
;
by country;
id date;
convert gdp=max_gdp_hist&j / transformin=(lag 1) transformout=(nomiss movmax &j);
convert gdp=centered_window_range / transformin=(*0 +1 cmovsum 2*&J+1 );
%if &j=3 %then %do;
convert gdp=gmean_future_rate_3 / transformin=(ratio 1 log cmovave ( 0 0 0 0 1 1 0) exp -1);
%end;
%else %if &j=6 %then %do;
convert gdp=gmean_future_rate_3 / transformin=(ratio 1 log cmovave ( 0 0 0 0 0 0 0 1 1 0) exp -1);
%end;
%else %if &j=9 %then %do;
convert gdp=gmean_future_rate_3 / transformin=(ratio 1 log cmovave ( 0 0 0 0 0 0 0 0 0 0 1 1 0) exp -1);
%end;
%else %do;
convert gdp=gmean_future_rate_3 / transformin=(ratio 1 log cmovave ( 0 0 0 0 0 0 0 0 0 0 1 1 0) exp -1);
%end;
run;
Since the only thing that changes is the parameter string in the brackets, you could create that with
data _null_;
length parmstr $50;
do i = 1 to &j;
parmstr = catx(' ',parmstr,put(i,best.));
end;
parmstr = trim(parmstr) !! ' 0 1 1 0';
call symput('parmstr',trim(parmstr));
run;
and so avoid the %if by having a single convert statement with &parmstr.
BTW what are you trying to do with
max_gdp_hist&j
I see no variable beginning with max_gdp_hist in your dataset. Are you trying to do an indirect reference on macro variables called max_gdp_hist3, max_gdp_hist6, max_gdp_hist9, max_gdp_hist12? If yes, where are they created?
And you go to great lengths creating the macro variable &k and then never use it. You only repeat identical code 4 times because of the
%do k_index=1 %to 4;
loop.
I am grateful for your support, KurtBremser.
Allow me to clarify some points you mentioned. The max_gdp_hist was to fulfill the needs of the research that “In the time series of gdp for several countries (part of the data is attached), we want to know the continuing performance of gdp of each country.”
1) We want to identify the date (maybe many observations would satisfy the requirement in the series) that was better than the maximum gdp value of the past 6 months and its future growth rate.
2) The posted coding was only part of the whole coding and &k would appear in somewhere at the other part of the coding.
3) The macro coding you posted is good enough for me. However, I wonder what would happen to “call symput” if the “if-then condition” is like the following instead of the previous one.
%if &j=3 %then %do;
convert prc=gmean_future_rate_3 / transformin=(ratio 1 log cmovave ( 0 0 0 0 1 1 0) exp -1);
%end;
%else %if &j=6 %then %do;
convert prc=gmean_future_rate_3 / transformin=(ratio 1 log cmovave ( 0 0 0 0 0 0 0 1 1 0 0 0 0) exp -1);
%end;
%else %if &j=9 %then %do;
convert prc=gmean_future_rate_3 / transformin=(ratio 1 log cmovave ( 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0) exp -1);
%end;
%else %do;
convert prc=gmean_future_rate_3 / transformin=(ratio 1 log cmovave ( 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 ) exp -1);
%end;
Well, you need to implemet your rule in the data step code that builds the string. The call symput just sets the macro variable to the contents of the string.
Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!
Learn the difference between classical and Bayesian statistical approaches and see a few PROC examples to perform Bayesian analysis in this video.
Find more tutorials on the SAS Users YouTube channel.