BookmarkSubscribeRSS Feed
☑ This topic is solved. Need further help from the community? Please sign in and ask a new question.
stataq
Quartz | Level 8

Hello,

I am try to setup a macro to build sub data set and define new macro variable (colvar, cols, in data, indata2)based on whether I have &indata2 exist or not before I call this macro "%m_setup". I tried many ways and still could not get it to work. Could anyone guide me on this?

 

&Indata. is always defined in my data.    &armvar and &col_ab are also definded already.

 

Please see my code below:

 

Please pardon me as I might have some silly errors in my codes, especially when to add % within a macro.

%macro m_setup;

data &indata._a; set &indata.; if armord=1; run;
data &indata._b; set &indata.; if armord=2; run;
data &indata._c; set &indata.; if armord=3; run;
data &indata._ab; set &indata.; if( armord=1 or armord=2) ; run;

/*%if "&indata2"  ne '' %then %do;*/
if  symexist('indata2') then do;
/*%if &indata2. ^=  %str() %then %do;*/
	data &indata2._a; set &indata2.; if armord=1; run;
	data &indata2._b; set &indata2.; if armord=2; run;
	data &indata2._c; set &indata2.; if armord=3; run;
	data &indata2._ab; set &indata2.; if( armord=1 or armord=2); run;
end;

data _null_;
   
  if "&armvar" eq 'ab' then do;
	  call symputx('cols'," &col_ab.");
	  call symputx('indata', "&indata._ab"); 
/*	  %if "&indata2" ne ''  %then %do;*/
	   %if %symexist('indata2') %then %do;
		call symputx('indata2', "&indata2._ab"); 
	 %end;
 end;

run;
%mend;
1 ACCEPTED SOLUTION

Accepted Solutions
Tom
Super User Tom
Super User

Looking at the code you are trying to use the macro to generate I suspect that the test you want is whether or not the DATASET named in the macro variable INDATA2 exists or not.  You probably might need to also test if the macro variable exist and possible if it has a non empty value first.

 

It is not a good practice to write a macro that references magic macro variables.  That is macro variables that are not input parameters and not even referenced any where in the code (or comments) until the magically appear in the middle of the macro definition.

 

I have no idea what you are trying to do in that last data _null_ step. 

 

But here is what I think you are trying to do with &INDATA and &INDATA2.

%macro m_setup;
%if not %symexist(indata) %then %do;
  %put ERROR: Required macro variable INDATA does not exist.;
%end;
%else %if not %sysfunc(exist(&indata)) %then %do;
  %put ERROR: Dataset &indata does not exist. ;
%else %do;
* Split &INDATA into 4 dataset based on ARMORD;
data &indata._a &indata._b &indata._c &indata._ab; 
  set &indata.; 
  if armord=1 then output &indata._a &indata._ab;
  if armord=2 then output &indata._b &indata._ab;
  if armord=3 then output &indata._c;
run;

  %if %symexist(indata2) %then %do;
    %if not %sysfunc(exist(&indata2)) %then %do;
      %put ERROR: Dataset &indata2 does not exist. ;
    %end;
    %else %do;

* Split &INDATA2 into 4 dataset based on ARMORD;
data &indata2._a &indata2._b &indata2._c &indata2._ab; 
  set &indata2.; 
  if armord=1 then output &indata2._a &indata2._ab;
  if armord=2 then output &indata2._b &indata2._ab;
  if armord=3 then output &indata2._c;
run;

    %end;
  %end;
%end;

%mend;

But I do not understand why it make sense to split the dataset into 4 pieces like that.

 

View solution in original post

5 REPLIES 5
PaigeMiller
Diamond | Level 26

Inside %symexist, there should be no quotes.


From now on, please don't dump a block of code for us to look at and say it doesn't work and provide no further explanation. Explain what you see that indicates it is not working. Also: if there is an error(s) in the log, show us the log; if the code doesn't produce the right output, show us the incorrect output and explain what the right output would be.


Adding: I agree with @Tom below, splitting the data up into four data sets seems like it doesn't really help anything, but makes the programming more difficult.

--
Paige Miller
Tom
Super User Tom
Super User

Looking at the code you are trying to use the macro to generate I suspect that the test you want is whether or not the DATASET named in the macro variable INDATA2 exists or not.  You probably might need to also test if the macro variable exist and possible if it has a non empty value first.

 

It is not a good practice to write a macro that references magic macro variables.  That is macro variables that are not input parameters and not even referenced any where in the code (or comments) until the magically appear in the middle of the macro definition.

 

I have no idea what you are trying to do in that last data _null_ step. 

 

But here is what I think you are trying to do with &INDATA and &INDATA2.

%macro m_setup;
%if not %symexist(indata) %then %do;
  %put ERROR: Required macro variable INDATA does not exist.;
%end;
%else %if not %sysfunc(exist(&indata)) %then %do;
  %put ERROR: Dataset &indata does not exist. ;
%else %do;
* Split &INDATA into 4 dataset based on ARMORD;
data &indata._a &indata._b &indata._c &indata._ab; 
  set &indata.; 
  if armord=1 then output &indata._a &indata._ab;
  if armord=2 then output &indata._b &indata._ab;
  if armord=3 then output &indata._c;
run;

  %if %symexist(indata2) %then %do;
    %if not %sysfunc(exist(&indata2)) %then %do;
      %put ERROR: Dataset &indata2 does not exist. ;
    %end;
    %else %do;

* Split &INDATA2 into 4 dataset based on ARMORD;
data &indata2._a &indata2._b &indata2._c &indata2._ab; 
  set &indata2.; 
  if armord=1 then output &indata2._a &indata2._ab;
  if armord=2 then output &indata2._b &indata2._ab;
  if armord=3 then output &indata2._c;
run;

    %end;
  %end;
%end;

%mend;

But I do not understand why it make sense to split the dataset into 4 pieces like that.

 

stataq
Quartz | Level 8

Thanks so much for the detailed explanation. Really appreciated. I just try to do some macro exercise. It is good lesson learned that we should check both macro variable and real dataset set existence.👍   

PaigeMiller
Diamond | Level 26

@stataq wrote:

Thanks so much for the detailed explanation. Really appreciated. I just try to do some macro exercise.


@stataq 

Part of learning to use macros is learning when NOT to use macros. Splitting data sets up is rarely a good strategy, although there are exceptions. Part of learning to use macros is writing working SAS code for one or two cases without macros and without macro variables,  as suggested by @Cynthia_sas and only after that is successful, turn the code into macro code.

--
Paige Miller
Cynthia_sas
SAS Super FREQ

Hi:

  I'm confused. SYMEXIST only checks the existance of a macro variable in any local or global symbol tables. So are you wanting to see whether the macro variable &indata2 exists or are you wanting to see whether the resolved value of &indata2, either a LIBREF or a DATASET object exists? I can see references to &indata. and &indata2. in your code. I do not see any parameters defined in your %macro definition and I don't see any place where you're assigning a value to &indata2. You say that &indata is 'always defined' but &indata is not the same macro variable as &indata2. Is there also ALWAYS a value assigned to &indata2? The advice I always give my students is that before they write a macro program definition, they should start from a working SAS program with minimal macro involvement in order to make sure that their program logic is correct and works as intended before introducing macro elements. So for example, if your goal is to create 4 different datasets based the value of the armord variable, (as shown at the top of your code), what did your working SAS program look like without any macro involvement?? Did you start with a working SAS program? If so, what did that starting program look like?

Cynthia

 

Ready to join fellow brilliant minds for the SAS Hackathon?

Build your skills. Make connections. Enjoy creative freedom. Maybe change the world. Registration is now open through August 30th. Visit the SAS Hackathon homepage.

Register today!
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.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 5 replies
  • 534 views
  • 2 likes
  • 4 in conversation