I have written a program (that gets copied from one study to another) that specifies a list of ID variables that will be used throughout several subprograms. I also have a couple of binary variables that are created by searching a table for the existence of a specified variable. If it exists, I want it included in the ID variable list; otherwise, it should be excluded.
STUDYPART_EXIST=0 if STUDYPART does not exist and 1 if it does.
BATCH_EXIST=0 if BATCH does not exist and 1 if it does.
This is a section of code that checks all 4 possible combinations of a variable existing to see if it is properly storing the necessary variable in the macro variable IDVARS:
%macro idvars (studypart_exist=, batch_exist=);
%if &stdypart_exist.=1 & &batch_exist.=1 %then %do;
%let idvars=%str(SITECOUNTRY SITEMNEMONIC SUBJECTNUMBERSTR STDYPART BATCH AESPID AETERM AESTDATC AEENDATC);
%end;
%if &stdypart_exist.=1 & &batch_exist.=0 %then %do;
%let idvars=%str(SITECOUNTRY SITEMNEMONIC SUBJECTNUMBERSTR STDYPART AESPID AETERM AESTDATC AEENDATC);
%end;
%if &stdypart_exist.=0 & &batch_exist.=1 %then %do;
%let idvars=%str(SITECOUNTRY SITEMNEMONIC SUBJECTNUMBERSTR BATCH AESPID AETERM AESTDATC AEENDATC);
%end;
%if &stdypart_exist.=0 & &batch_exist.=1 %then %do;
%let idvars=%str(SITECOUNTRY SITEMNEMONIC SUBJECTNUMBERSTR AESPID AETERM AESTDATC AEENDATC);
%end;
%put &idvars.;
%mend idvars;
%idvars (studypart_exist=0, batch_exist=0);
%idvars (studypart_exist=0, batch_exist=1);
%idvars (studypart_exist=1, batch_exist=0);
%idvars (studypart_exist=1, batch_exist=1);
I am fine using my original code, but just out of curiosity (and in an attempt to continue learning something new) is there a way to shorten my code? If I had to conditionally include a new variable, then my code includes 8 combinations. Another one would mean 16, etc. It would be nice to keep this simple and just have a single line per conditional variable if possible.
I decided to try to use IF statements, but those are considered text and not IF statements. Is there a way to simplify what I'm already doing?
%macro idvars (studypart_exist=, batch_exist=);
%let idvars=%str(SITECOUNTRY SITEMNEMONIC SUBJECTNUMBERSTR)
%if &stdypart_exist.=1 %then %do; STDYPART %end;
%if &batch_exist.=1 %then %do; BATCH %end;
%str(AESPID AETERM AESTDATC AEENDATC);
%put &idvars.;
%mend idvars;
%idvars (studypart_exist=0, batch_exist=0);
%idvars (studypart_exist=0, batch_exist=1);
%idvars (studypart_exist=1, batch_exist=0);
%idvars (studypart_exist=1, batch_exist=1);
Hi @djbateman,
How about using macro variables of the form
%let batch=BATCH; /* if it exists */
%let batch=; /* otherwise */
instead of BATCH_EXIST etc.?
Then you could simply define
%let idvars=SITECOUNTRY SITEMNEMONIC SUBJECTNUMBERSTR &STDYPART &BATCH AESPID AETERM AESTDATC AEENDATC;
(no macro IDVARS needed) and the non-existing variables would disappear automatically from the list (leaving a double blank, which you could compress if necessary, e.g. with %CMPRES).
If you needed the 0 or 1 from the former xxx_EXIST variables in other places of the program, you could easily generate them, e.g., in the form
%eval(&batch ne)
Hi @djbateman,
How about using macro variables of the form
%let batch=BATCH; /* if it exists */
%let batch=; /* otherwise */
instead of BATCH_EXIST etc.?
Then you could simply define
%let idvars=SITECOUNTRY SITEMNEMONIC SUBJECTNUMBERSTR &STDYPART &BATCH AESPID AETERM AESTDATC AEENDATC;
(no macro IDVARS needed) and the non-existing variables would disappear automatically from the list (leaving a double blank, which you could compress if necessary, e.g. with %CMPRES).
If you needed the 0 or 1 from the former xxx_EXIST variables in other places of the program, you could easily generate them, e.g., in the form
%eval(&batch ne)
Oh my goodness! How simple could it have been? I feel kind of ridiculous for even posting my question now. But thank you for showing me what I should have already known. Thanks!
Just use multiple %LET statements.
%macro idvars (studypart_exist=, batch_exist=);
%let idvars=SITECOUNTRY SITEMNEMONIC SUBJECTNUMBERSTR;
%if &stdypart_exist %then %let idvars=&idvars STDYPART;
%if &batch_exist %then %let idvars=&idvars BATCH;
%let idvars=&idvars AESPID AETERM AESTDATC AEENDATC;
%put &idvars.;
%mend idvars;
PS Why were you adding macro quoting to characters that do not (and could not) contain anything that needs quoting?
It's finally time to hack! Remember to visit the SAS Hacker's Hub regularly for news and updates.
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.