DATA Step, Macro, Functions and more

how to resolve macro variable by calling a macro from datastep.

Accepted Solution Solved
Reply
Contributor
Posts: 62
Accepted Solution

how to resolve macro variable by calling a macro from datastep.

HI

I have two different datasets where I want to identify the matching values .

 

For example in the below code I have used both similar datasets (in real both are different). Here I would like to get local as the macro variable but uanble to graple the value with in one call. could any one please help me how to resolve macro variable by calling a macro from datastep.

 

%global temp;

%let temp = %str(std='yes');

%macro test(name);

data _null_;

set sashelp.class;

if name=&name then do;

call symput("temp",%str(local='yes'));

stop;

end;

%mend;

data xyz;

set sashelp.class;

call execute('%test('||name||')');

&temp;

run;


Accepted Solutions
Solution
‎01-01-2016 09:41 AM
Super User
Super User
Posts: 6,502

Re: how to resolve macro variable by calling a macro from datastep.

One way to code such a test is to take advantage of the CANCEL option on the RUN statement. So first create an empty macro variable and then while reading the first file conditionally set the macro variable to contain the keyword CANCEL.  Then reference the macro variable in the second data step that reads the second data file.

 

%let run_cancel=;
data _null_;
   infile 'file1' ;
   input;
   if _infile_=: 'RSS' then do;
      call symputx('run_cancel','cancel');
      stop;
  end;
run;
data want ;
   infile 'file2' ;
   input ....... ;
run &run_cancel ;

View solution in original post


All Replies
Respected Advisor
Posts: 3,124

Re: how to resolve macro variable by calling a macro from datastep.

Check SYMGET() or RESOLVE().

Contributor
Posts: 62

Re: how to resolve macro variable by calling a macro from datastep.

did not resolve my issue, if possible could you please try the sample code.

Respected Advisor
Posts: 3,124

Re: how to resolve macro variable by calling a macro from datastep.

Your description need be elaborated more. There are more than one macro variables in your code, please comment your code in detail, so that people can know where/what/how, then we start from there.
Super User
Super User
Posts: 6,502

Re: how to resolve macro variable by calling a macro from datastep.

You should use PROC COMPARE to compare datasets.  

 

As to your posted code if you just look at the SAS log it will be obvious what is happening and why that method is not very useful.

 

First the data set XYZ is created and then there are 19 more data steps that are generated by your CALL EXECUTE() statement that are run.  This is becuase the CALL EXECUTE function just pushes code onto the stack to be executed after the current data step finishes.

 

Also notice that the data set XYZ will have the variable STD set to 'yes' since when that data step was prepared for execution the value of the TEMP macro variable was std='yes'.  So your data step is resolves to:

 

data xyz;
  set sashelp.class;
  call execute('%test('||name||')');
  std='yes';
run

Now the CALL EXECUTE will run the %TEST() macro and push any code that it generates onto the stack so that it can execute after the XYZ dataset is created.  So for example it will push code like this data step.

 

data _null_;
  set sashelp.class;
  if name=Alfred then do;
    call symput("temp",local='yes');
    stop; 
  end;

In addition to problem of the code running after the XYZ step is finished there are other problems with this code. First there is no variable named ALFRED in the SASHELP.CLASS dataset. I assume that you intended to generate "Alfred" instead so that it would be interpreted as a string literal instead of a variable name.  So the IF statement is never true so the CALL SYMPUT() function never runs.  But  note that it also has trouble since you are referencing the variable LOCAL which does not exist. Since this will never be equal to 'yes' the CALL SYMPUT statement would have always set the macro variable TEMP to the number zero converted to a text string using the BEST12. format, so eleven spaces followed by the digit 0.  Also notice that your generated code does not contain a 'RUN;' statement to terminate the data step.

Super Contributor
Posts: 426

Re: how to resolve macro variable by calling a macro from datastep.

Could you please tell me how the call execute will work in the code below? I know that it will call the 'test' macro , but I don't understand the other thing which is enclosed in single quotes '||name||'

 

 

data xyz;
  set sashelp.class;
  call execute('%test('||name||')');
  std='yes';
run

 

Thanks in advance!

 

Super User
Super User
Posts: 6,502

Re: how to resolve macro variable by calling a macro from datastep.

|| is the concatenation operator.  So '%test(' || name || ')' says to sandwich the value of the variable NAME between the two string literals. So it if the value of NAME is 'Alfred  ' then the string passed to CALL EXECUTE will be '%test(Alfred  )'.  Now that SAS has introduced the CAT... series of functions I find that I use them more often than the simple concatenation operator.  So you could use CATS('%test(',name,')') instead.  Note that the CATS() function will also trim the trailing spaces from the value of the NAME variable.

 

If you use this syntax then the %TEST() macro call will execute immediately and any SAS code it generates will be pushed onto the stack to run after the current data step finishes.  But any macro code that the macro has will execute immediately.  That is why normally it is helpful to add %NRSTR() macro function around the macro call to prevent the macro from executing immediately.  Instead the macro all will be placed on the stack and then the macro will execute after the current data step finishes.

 

data xyz;
  set sashelp.class;
  call execute('%nrstr(%test)('||name||')');
  std='yes';
run
Contributor
Posts: 62

Re: how to resolve macro variable by calling a macro from datastep.

Hi Babloo,

 

the enclosed one is a parameter to the macro.

Example: If you want to pass some value to the macro then you can pass the variable value in it for each observation.

if you have a dataset with name as the variable name (4 names) then all four times it will pass and call the calling macro.

 

data test;

  input name $;

  datalines;

  kumar

  akash

  vinay

  babloo

;

 

%macro printmacro(name);

  %put These are very good guys : &name.;

%mend;

 

data _null_;

  set test;

  call execute('%test('||name||');

run;

Here the print macro  will be called 4 times (as many observations as test dataset has) and prints the output to the log.

 

Hope answered the question.

Super User
Posts: 10,548

Re: how to resolve macro variable by calling a macro from datastep.

Here's one way to find if a specific value occurs in a data set for a variable:

 

proc sql noprint;
   select (count(name)>0) into : temp
   from sashelp.class
   where name="&name";
quit;

The macro variable temp will have a value of 1 (found) or 0 (not found). Note that just as your attempted code would not match ALFRED to Alfred, case or leading spaces will not match. You might want to consider addressing those points for your application.

 

Super User
Super User
Posts: 6,502

Re: how to resolve macro variable by calling a macro from datastep.

If you just want to match records on value of a variable then use a MERGE statement.

 

data want ;
    merge one two ;
    by id;
run;
Contributor
Posts: 62

Re: how to resolve macro variable by calling a macro from datastep.

Thank you for the replies. well I have a confusion of how call execute works. My issue is to restrict the reading of text file based on condtion (so I created a macro and a sample example).

 

For example:

I have to read a text file

 

filename in "c:/temp.txt";

data test;

  infile in truncover;

  input  x $500.;

  if x > 'some value then only i need to create dataset or else discard reading the file';

/*Here i might need previous observations if this condition is true */

/*Value of x may come in nth row */

run;

 

data test;

infile in truncover;

Super User
Super User
Posts: 6,502

Re: how to resolve macro variable by calling a macro from datastep.

Is this the same problem or a new one?

Not much way to do this without reading the file twice. Once to determine if the problem value exists and then again to generate the dataset.  Or you might actually be able to use CALL EXECUTE for this problem by creating the dataset and then conditionally deleting it (or perhaps renaming it).

 

data WANT;
  infile "c:\temp.txt" truncover;
  input x $500.;
  if x > 'some value then only i need to create dataset or else discard reading the file' then do;
    call execute('proc delete data=WANT;run;');
    stop;
  end;
run;
Contributor
Posts: 62

Re: how to resolve macro variable by calling a macro from datastep.

Thanks tom,

 

Its the same issue which I posted . I had some logic running and was not working in between to solve reading text file.

 

 

 

 

Contributor
Posts: 62

Re: how to resolve macro variable by calling a macro from datastep.

want to add few more points

1. I thought to create a flag (retain varialbe) and continue reading the text file.

2. text file reading has many conditions and want to improve performance.

 

if there is any other solution to read a text file (optimized way, as it got 100's of condtions in it)

Super User
Super User
Posts: 6,502

Re: how to resolve macro variable by calling a macro from datastep.

In general if the question is how to read a complicated text file into a nice structured data set then conditional programming is the answer and not generated code.  Figure out a data structure that can store the information and then write a data step (or series of steps) to create that structure from the source file.  For example look at this posting on Stack Overflow.  https://stackoverflow.com/questions/34533980/reading-hierarchicalish-data-into-sas/34547963#34547963

 

☑ This topic is solved.

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

Discussion stats
  • 17 replies
  • 508 views
  • 2 likes
  • 5 in conversation