BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
djbateman
Lapis Lazuli | Level 10

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);

 

1 ACCEPTED SOLUTION

Accepted Solutions
FreelanceReinh
Jade | Level 19

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)

 

View solution in original post

3 REPLIES 3
FreelanceReinh
Jade | Level 19

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)

 

djbateman
Lapis Lazuli | Level 10

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!

Tom
Super User Tom
Super User

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?

hackathon24-white-horiz.png

The 2025 SAS Hackathon has begun!

It's finally time to hack! Remember to visit the SAS Hacker's Hub regularly for news and updates.

Latest Updates

How to Concatenate Values

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.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 3 replies
  • 1740 views
  • 0 likes
  • 3 in conversation