I have the following code running:
%macro central_bank (reg, begin, end);
%do i= &begin. %to &end.;
data ®.&i.;
set ®.&i.;
if Code= "US28" or Code= "US29" then do;
if Actual= 9999 or Surv_Med= 9999 then delete;
Surp_B_®.&i.= Surp_Bloom;
SD_B_®.&i.= Std_Dev_Surv;
Diff_®.&i.= Actual-Surv_Med;
Ratio_®.&i.= Actual/Surv_Med; end;
PS_®.&i.= 1;
Year= year (Date);
Interval= (int(Time)/300)+1;
run;
proc sort data= ®.&i.;
by Date Interval;
run;
%if &begin.= 28 or &begin.= 29 %then %do;
proc sql;
create table C_®.&i. as
select *, STD(Diff_®.&i.) as SD_®.&i., Diff_®.&i./STD(Diff_®.&i.) as Surp_®.&i. from ®.&i.;
quit;
proc means data= C_®.&i. nway noprint;
class Year;
output out= YSC_®.&i. STD(Diff_®.&i.)= YSD_®.&i.;
run;
proc sort data= C_®.&i.;
by Date Year;
run;
proc sort data= YSC_®.&i.;
by Year;
run;
data C_®.&i.;
merge C_®.&i. YSC_®.&i.;
by Year;
run;
proc sort data= C_®.&i.;
by Date Interval;
run;
data C_®.&i.;
set C_®.&i.;
YSurp_®.&i.= Diff_®.&i./YSD_®.&i.;
run;
data C_®.&i.;
set C_®.&i.;
keep Date Time Interval PS_®.&i. Diff_®.&i. SD_®.&i. SD_B_®.&i. YSD_®.&i. Surp_®.&i. Surp_B_®.&i. YSurp_®.&i. Ratio_®.&i.;
run;
%end;
%else %if &begin.= 30 or &begin.= 31 %then %do;
data C_®.&i.;
set ®.&i.;
keep Date Time Interval PS_®.&i.;
run;
%end;
%end;
%mend central_bank;
%central_bank (US, 28, 31);
Though I have coded so that some part of the code gets executed for a certain value of the macro variable, I see that the whole code gets run, and %if condition does not work.
Where did I go wrong?
Much thanks.
Regards.
First, write your code in structured way that lets you see logical blocks; as it is, that ugly spaghetti is close to un-decipherable. See Maxim 12.
Next, use %put to follow your macro logic:
%macro central_bank (reg, begin, end);
%do i = &begin. %to &end.;
%put loop iteration for &i.;
%if &begin.= 28 or &begin.= 29 %then %do;
%put branch for begin in (28,29);
%end;
%else %if &begin.= 30 or &begin.= 31 %then %do;
%put branch for begin in (30,31);
%end;
%end;
%mend central_bank;
%central_bank (US, 28, 31);
The log from that (see Maxim 2) tells you that your second %if prevents the second block from executing:
37 %macro central_bank (reg, begin, end); 38 39 %do i = &begin. %to &end.; 40 41 %put loop iteration for &i.; 42 43 44 %if &begin.= 28 or &begin.= 29 %then %do; 45 46 %put branch for begin in (28,29); 47 48 %end; 49 50 %else %if &begin.= 30 or &begin.= 31 %then %do; 51 52 %put branch for begin in (30,31); 53 54 %end; 55 56 %end; 2 Das SAS System 07:58 Wednesday, February 13, 2019 57 58 %mend central_bank; 59 60 %central_bank (US, 28, 31); loop iteration for 28 branch for begin in (28,29) loop iteration for 29 branch for begin in (28,29) loop iteration for 30 branch for begin in (28,29) loop iteration for 31 branch for begin in (28,29)
Sideways to your question, you would save yourself
- A lot of coding and maintenance
- A lot of processor and storage space
Simply by changing your approach to your problem. I can tell this as soon as I see coding like:
data ®.&i.;
and
Surp_B_®.&i.
This shows that your are creating lots of datasets for the same data and that in those datasets you are creating lots of variables. Both of these show a badly worked out data modelling structure.
Without seeing the data/process in full my suggested change would be to create a record (observation) for each of the data items like:
PARAM RESULT...
SURP_B_US_1 ....
SURP_B_US_2 ...
Then instead of creating a new dataset (i.e. read/writes for each group) use a by group to do the calculations in one simple datastep/means output by your by groups and params, to get one complete results dataset out. This would give you 1 dataset in, 1 dataset out (1*read/write) and very simple Base SAS which is easy to code and maintain. The only reason for transposed data is for output purposes and this can be achieved by a proc transpose before proc report.
SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!
SAS' Charu Shankar shares her PROC SQL expertise by showing you how to master the WHERE clause using real winter weather data.
Find more tutorials on the SAS Users YouTube channel.