Try this : Not optimized though.. but should work.... data have; input @1 label1 $ @3 label2 $ @5 label3 $1. @7 condition $; datalines; a d p code1 a d p code7 a e q code2 a e q code3 b p code4 b a r code5 d a r code6 run; %macro rules (meta_rule_table_name); /* open the meta rules table*/ %let meta_rule_table_id=%sysfunc(open(&meta_rule_table_name,i)); /* fetch the first record */ %let rc=%sysfunc(fetch(&meta_rule_table_id)); %if &rc ne 0 %then %do; %put something is wrong ...; %end; %else %do; /* read label1, label2, label3 and condition variables for the very first record */ %let label1=%sysfunc(getvarc(&meta_rule_table_id, %sysfunc(varnum(&meta_rule_table_id,label1)))); %let label2=%sysfunc(getvarc(&meta_rule_table_id, %sysfunc(varnum(&meta_rule_table_id,label2)))); %let label3=%sysfunc(getvarc(&meta_rule_table_id, %sysfunc(varnum(&meta_rule_table_id,label3)))); %let condition=%sysfunc(getvarc(&meta_rule_table_id, %sysfunc(varnum(&meta_rule_table_id,CONDITION)))); /* store the current values for comparision with the next record's values*/ %let prev_label1 = &label1; %let prev_label2 = &label2; %let prev_label3 = &label3; %let reset = 1; %if &reset eq 1 %then %do; %put case when label1 eq "&label1" then case when label2 eq "&label2" then case when label3 eq "&label3" then case WHEN (&condition); %let reset = 0; %end; /* fetch the next record of the meta rules table */ %let rc=%sysfunc(fetch(&meta_rule_table_id)); /* as long as there is a record in the rules table keep looping */ %do %while (&rc eq 0); /* read the variables for the fetched record */ %let label1=%sysfunc(getvarc(&meta_rule_table_id, %sysfunc(varnum(&meta_rule_table_id,label1)))); %let label2=%sysfunc(getvarc(&meta_rule_table_id, %sysfunc(varnum(&meta_rule_table_id,label2)))); %let label3=%sysfunc(getvarc(&meta_rule_table_id, %sysfunc(varnum(&meta_rule_table_id,label3)))); %let condition=%sysfunc(getvarc(&meta_rule_table_id, %sysfunc(varnum(&meta_rule_table_id,CONDITION)))); /* if the current label1 differs from the previous label1 then all three if conditions need to change */ %if &label1 ne &prev_label1 %then %do; %let reset = 1; %put then "Y"; %put ELSE "N" end; %put ELSE "N" end; %put ELSE "N" end; %if &reset eq 1 %then %do; %put when label1 eq "&label1" then case when label2 eq "&label2" then case when label3 eq "&label3" then case WHEN (&condition); %let reset = 0; %end; %end; /* if the current label2 differs from the previous label2 then only two if conditions need to change */ %else %if &label2 ne &prev_label2 %then %do; %let reset = 1; %put then "Y"; %put ELSE "N" end; %put ELSE "N" end; %if &reset eq 1 %then %do; %let reset = 0; %put when label2 eq "&label2" then case when label3 eq "&label3" then case when (&condition) ; %end; %end; /* if the current label3 differs from the previous label3 then only one if condition needs to change */ %else %if "&label3" ne "&prev_label3" %then %do; %let reset = 1; %put then "Y"; %put ELSE "N" end; %if &reset eq 1 %then %let reset = 0; %put when label3 eq "&label3" then case WHEN (&condition); %end; /* if label1, label2, label3 are same for both current and previous records in the table then only print the subsetting IF statement */ %else %do; %if &reset eq 1 %then %do; %put (&condition) ; %end; %else %do; %put or(&condition) ; %end; %let reset=0; %end; /* store the current values for comparision with the next record's values before the next fetch */ %let prev_label1 = &label1; %let prev_label2 = &label2; %let prev_label3 = &label3; /* fetch the next record of the meta rules table */ %let rc=%sysfunc(fetch(&meta_rule_table_id)); %end; /* end of %do %while ... */ %put then "Y"; %put ELSE "N" end; %put ELSE "N" end; %put ELSE "N" end; %end; /* close the meta rules table */ %let rc=%sysfunc(close(&meta_rule_table_id)); %put ELSE "N" end as Meta1; %mend rules; %rules(have);
... View more