data driven code with Macros

Accepted Solution Solved
Reply
New Contributor
Posts: 2
Accepted Solution

data driven code with Macros

While using this code

%macro SPLIT (DATA = , VAR =) ;
PROC SORT DATA = &DATA (KEEP = &VAR) OUT = SORT_&VAR NODUPKEY;
BY &VAR;

DATA _NULL_;
SET SORT_&VAR end = final;
CALL SYMPUTX ("&VAR"!!left(_n_), &VAR);
if final then call symputx('Count',_n_);

 

%do i = 1 %to &count;
data &&&VAR&i;
set &DATA;
where &VAR = "&&&VAR&i";
run;
proc print data = &&&VAR&I;
title "Customer Data for &VAR: &&&VAR&I ";
%end;
%mend SPLIT;

%SPLIT (DATA = ORION.EMPLOYEE_PAYROLL, VAR = EMPLOYEE_GENDER)

 

I am getting error that Employee_gender1 was not resolved, cant  understand why because  EMPLOYEE_GENDER2 was resolved to Male; and its clearly visible in datafile sort_EMPLOYEE_GENDER that variable employee_gender has only two values - Female and Male.


Accepted Solutions
Solution
‎05-08-2018 02:49 AM
Super User
Posts: 6,781

Re: data driven code with Macros

Posted in reply to Pradeeptdalal28

It's generally a good idea to add RUN statements ending your DATA and PROC steps.  In this case, it's an essential idea.  Add them, and the problem should vanish.

View solution in original post


All Replies
Solution
‎05-08-2018 02:49 AM
Super User
Posts: 6,781

Re: data driven code with Macros

Posted in reply to Pradeeptdalal28

It's generally a good idea to add RUN statements ending your DATA and PROC steps.  In this case, it's an essential idea.  Add them, and the problem should vanish.

New Contributor
Posts: 2

Re: data driven code with Macros

Posted in reply to Astounding
Thanks mate, I am using SAS Studio where its Run; statement is not generally considered mandatory, but it solved the problem. Could you elaborate how it works because when "Country" is taken as variable instead of Gender in orion.customer, same code worked without any problem
Super User
Posts: 13,563

Re: data driven code with Macros

Posted in reply to Pradeeptdalal28

@Pradeeptdalal28 wrote:
Thanks mate, I am using SAS Studio where its Run; statement is not generally considered mandatory, but it solved the problem. Could you elaborate how it works because when "Country" is taken as variable instead of Gender in orion.customer, same code worked without any problem

The same rules for data/proc step boundaries for execution exist in the other forms of SAS as well.

However using them explicitly is still a good idea. As you have just discovered and @Astounding provided just one of the potential issues when using macro code.

 

You don't have to name data sets in a data step either. SAS will happily create a new data set every time you run something like:

data;
  set sashelp.class; 
run;

of course keeping track of which dataN you actually want can become a chore.

 

You also do not have to name the data set used by many procs for input:

proc print;
run;

will happily print the last created data set.

 

In macro's using either of these code short cuts is very likely to lead to unexpected results, especially if your procedure references a variable that isn't actually in the last created data set.

 

"Have to" versus "good idea" decisions often result from experience (often defined as learning when something fouls up epically).

Super User
Posts: 6,781

Re: data driven code with Macros

Posted in reply to Pradeeptdalal28

There are too many unknowns to speculate about why the program would work in some cases.  For example, is there a global macro variable named COUNT?

 

Here's the reason that RUN is necessary.

 

DATA and PROC statements don't run until SAS "knows" that the step is complete.  Usually that means SAS encounters a subsequent DATA, PROC, or CARDS statement.

 

In this case, the DATA _NULL_ step doesn't run soon enough.  It's conceivable that the %DO loop that follows would be adding more statements that should be part of the same DATA step.  So the DATA _NULL_ step doesn't actually run until SAS encounters

 

DATA &&&VAR&I;

 

But resolving that second DATA statement requires that the DATA _NULL_ step already has executed, to create the macro variable that becomes the name of the next data set.  RUN cures the timing issue, forcing the DATA _NULL_ step to finish before executing the %DO loop.

☑ This topic is solved.

Need further help from the community? Please ask a new question.

Discussion stats
  • 4 replies
  • 144 views
  • 0 likes
  • 3 in conversation