why you can't use a macro funcation like %scan inside of a data step

Accepted Solution Solved
Reply
Regular Contributor
Posts: 152
Accepted Solution

why you can't use a macro funcation like %scan inside of a data step

[ Edited ]

Hi I think this is a very basic question.

why I can't use %scan or some other macro function inside of a datastep.

Is this because data step is reading value from PDV and %scan is creating a text?

 

 

%let a=%str(a_b);

 

data a;

a= "'"||%scan(&a,2,_)||"'";

run;

 

I wonder why the above program won't work.

 

please provide detailed explaination and refer me to any document if it is relevant.

 

Thanks


Accepted Solutions
Solution
‎05-17-2017 04:34 AM
Super User
Posts: 7,431

Re: why you can't use a macro funcation like %scan inside of a data step

[ Edited ]

gyambqt wrote:

But if I didn't use the || to concanate quotation mark together around b , I believe the treat b as a variable rather than value.

but here I used || so the final resolved value should be a='b'..... am I wrong?

 

a= "'"||%scan(&a,2,_)||"'";


Here you have three items that are concatenated:

- a string literal containing a single quote

- a macro call that will resolve to the text (not string literal!!) b and therefore be recognized as a variable name

- another string literal containing a single quote.

For the data step this means

"concatenate a single quote with the contents of b and another single quote"

 

To create the simple literal "b" for assignmenmt to data step variable a, use

a= "%scan(&a,2,_)";

 

---------------------------------------------------------------------------------------------
Maxims of Maximally Efficient SAS Programmers

View solution in original post


All Replies
Valued Guide
Posts: 2,177

Re: why you can't use a macro funcation like %scan inside of a data step

All about timing
Compile time : is macro time
Run time : observation time
Super User
Posts: 7,431

Re: why you can't use a macro funcation like %scan inside of a data step

The macro processor is a pre-processor. Anytime the SAS interpreter encounters a macro trigger (& or %), it sends all text of the trigger to the macro processor. This then deals with it and returns (or not, ie if a %put just writes to the log) text to the SAS interpreter for further execution.

So all macro triggers are resolved before a data or procedure step starts to run.

---------------------------------------------------------------------------------------------
Maxims of Maximally Efficient SAS Programmers
Super User
Posts: 3,235

Re: why you can't use a macro funcation like %scan inside of a data step

[ Edited ]

As a general rule use %scan when you are writing macro code statements and use the SCAN function in SAS code. Believe me it's a lot easier that way and it works:

 

%let a=%str(a_b);
 
data a;
  a = scan("&a", 2, "_");
run;

 

Super User
Posts: 5,365

Re: why you can't use a macro funcation like %scan inside of a data step

It's partly what you mentioned (processing text vs. processing data in the PDV).  But it's more than that.  Macro language constructs your program.  It doesn't process your data.  Picture this stand-alone statement:

 

%let b%scan(a,2,_);

 

Macro language would process the text "a", and would return a null string since there is no second word within the text "a".

 

In the context of your program, macro language does the same thing.  It processes "a" before your DATA step begins to run, as part of the process of compiling the DATA step statements and determining what statements should become part of the DATA step.  If you wanted macro language to return "b" instead (the second word within "a_b", you could get that with:

 

%let a = a_b;

%let b%scan(&a,2,_);

 

But none of that processing takes place within a DATA step.  All of it takes place as part of the compilation process that determines what statements the DATA step contains.  So consider your original program:

 

%let a = a_b;

data a;

a= "'"||%scan(a,2,_)"'";

run;

 

%SCAN runs before the DATA step begins, and generates this program:

 

data a;

a= "'"||"'";

run;

 

The bottom line:  macro language constructs a program.  It doesn't process your data.

 

Regular Contributor
Posts: 152

Re: why you can't use a macro funcation like %scan inside of a data step

I wonder why %scan below can't resolved to "b" 

%let a = a_b;
data a;
a= "'"||%scan(a,2,_)"'";
run;

i thought %scan would be  resolved to b before data step get executed.

Regular Contributor
Posts: 152

Re: why you can't use a macro funcation like %scan inside of a data step

Sorry I had a typo error . The code is fixed now.

thanks

Super User
Posts: 5,365

Re: why you can't use a macro funcation like %scan inside of a data step

Even in your fixed code, a means a.  It's just a letter. It has no connection to any variable in any DATA step.  Macro language doesn't require quotes for it to treat characters as text.  That's the default interpretation:  characters are text whether they have quotes around them or not.

Regular Contributor
Posts: 152

Re: why you can't use a macro funcation like %scan inside of a data step

I don't quite understand. 

Doesn't %scan(&a,2,_) resolved to  %scan(a_b,2,_) further resolved to b?

b with quotation should be treated as value?

Super User
Posts: 7,431

Re: why you can't use a macro funcation like %scan inside of a data step

The ONE IMPORTANT question has not yet been asked: what are you trying to achieve? Do you want to parameterize the use of a data step variable in a data step, or do you want to parameterize a value in a data step?

---------------------------------------------------------------------------------------------
Maxims of Maximally Efficient SAS Programmers
Super User
Posts: 5,365

Re: why you can't use a macro funcation like %scan inside of a data step

In macro language, b is not a value.  b is a letter that might be part of a SAS statement.  For example, after generating b with the %SCAN function, you would have this statement:

 

%let a = a_b;

%let b = %scan(&a, 2, _);

 

The macro variable &b contains the letter b.  But if it were part of this DATA step statement that would cause a problem:

 

%let a = a_b;

data a;
a= "'"||%scan(&a,2,_)"'";
run;

 

The DATA step statement would look like this:'

 

a = "'" ||b"'";

 

That's not a valid DATA step statement.

Regular Contributor
Posts: 152

Re: why you can't use a macro funcation like %scan inside of a data step

But if I didn't use the || to concanate quotation mark together around b , I believe the treat b as a variable rather than value.

but here I used || so the final resolved value should be a='b'..... am I wrong?

 

a= "'"||%scan(&a,2,_)||"'";

Solution
‎05-17-2017 04:34 AM
Super User
Posts: 7,431

Re: why you can't use a macro funcation like %scan inside of a data step

[ Edited ]

gyambqt wrote:

But if I didn't use the || to concanate quotation mark together around b , I believe the treat b as a variable rather than value.

but here I used || so the final resolved value should be a='b'..... am I wrong?

 

a= "'"||%scan(&a,2,_)||"'";


Here you have three items that are concatenated:

- a string literal containing a single quote

- a macro call that will resolve to the text (not string literal!!) b and therefore be recognized as a variable name

- another string literal containing a single quote.

For the data step this means

"concatenate a single quote with the contents of b and another single quote"

 

To create the simple literal "b" for assignmenmt to data step variable a, use

a= "%scan(&a,2,_)";

 

---------------------------------------------------------------------------------------------
Maxims of Maximally Efficient SAS Programmers
Regular Contributor
Posts: 152

Re: why you can't use a macro funcation like %scan inside of a data step

Thanks!

Valued Guide
Posts: 2,177

Re: why you can't use a macro funcation like %scan inside of a data step

Of course, there always exception to rules.
So the RESOLVE() data step function invokes the macro language environment processor to "resolve" the string parameter as if it is macro language syntax.
This use of the macro language provides a very different performance to the macro language processing which occurs in the usual way. This becomes most obvious when you think about doing the "resolve" on every data step iteration.... imagine a 100 million row table through a data step using RESOLVE()
☑ This topic is solved.

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

Discussion stats
  • 21 replies
  • 234 views
  • 1 like
  • 5 in conversation