I have some errors to create the following macro, can someone help me find and solve them?
%macro diag_hist(diag, code_list, num, single_code, single_code_l);
data &diag;
set temp;
%if single_code = 1 %then %do;
%if substr(code,1,&num) not in (&code_list) or code ~= &single_code_l %then delete;
%end;
%else %do;
%if substr(code,1,&num) not in (&code_list) %then delete;
%end;
run;
%mend;
%let code_list = "Z87" "T78" "T80" "T88" "R57";
%let single_code_l = "T39.395A";
%diag_hist(anaphylaxis, &code_list, 1, 3, &single_code_l); /*The macro variables code_list and single_code_l will be used in the above macro function as parameters.*/
There must be some errors in the if-else statement. Can someone help me figure them out! Appreciating your help!
Always post the SAS log for such questions.
I guess single_code should be &single_code
%if single_code = 1 %then %do;
That's a wild mixture of SAS code and Macro code. I guess your %IF and %THEN should be on SAS language level as IF and THEN.
%if substr(code,1,&num) not in (&code_list) or code ~= &single_code_l %then delete;
In general: First write your logic using macro free SAS code and only if that fully works make things dynamic by "macrotizing" it.
You use a macro to generate SAS code.
So currently the main structure of the SAS code your macro is generating is:
data &diag;
set temp;
...
run;
So what SAS code do you want to generate there to replace the ... ?
Probably NOT the code your macro is trying to generate.
Right now your first %IF test is always FALSE because the letter s can never equal to digit 1.
Your second %IF is definitely going to be TRUE for the values you passed because the macro variables on the right side of your tests contain quote characters and the strings on the left side do not.
So you are trying to run this invalid DATA step.
data &diag;
set temp;
delete run;
Most likely you wanted something like:
%macro diag_hist(diag, code_list, num, single_code, single_code_l);
data &diag;
set temp;
if &single_code = 1 then do;
if substr(code,1,&num) not in (&code_list) or code ne &single_code_l then delete;
end;
else do;
if substr(code,1,&num) not in (&code_list) then delete;
end;
run;
%mend;
So the only code generation you want the macro to do is to replace the macro variable reference with the strings passed in during the call to the macro.
Turn on the MPRINT option to see what code your macro has generated.
67 options mprint; 68 %diag_hist 69 (diag=anaphylaxis 70 ,code_list="Z87" "T78" "T80" "T88" "R57" 71 ,num= 1 72 ,single_code= 3 73 ,single_code_l= "T39.395A" 74 ) MPRINT(DIAG_HIST): data anaphylaxis; MPRINT(DIAG_HIST): set temp; MPRINT(DIAG_HIST): if 3 = 1 then do; MPRINT(DIAG_HIST): if substr(code,1,1) not in ("Z87" "T78" "T80" "T88" "R57") or code ne "T39.395A" then delete; MPRINT(DIAG_HIST): end; MPRINT(DIAG_HIST): else do; MPRINT(DIAG_HIST): if substr(code,1,1) not in ("Z87" "T78" "T80" "T88" "R57") then delete; MPRINT(DIAG_HIST): end; MPRINT(DIAG_HIST): run;
I don't think that code is going to work either. The one digit string generated by SUBSTR() function is never going to match your three character strings you are passing in.
So you should first get the data step to run without any macro variables. Then you can start trying to replace some of the code with macro variable references.
SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!
Learn how use the CAT functions in SAS to join values from multiple variables into a single value.
Find more tutorials on the SAS Users YouTube channel.
Ready to level-up your skills? Choose your own adventure.