BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
gyambqt
Obsidian | Level 7

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

1 ACCEPTED SOLUTION

Accepted Solutions
Kurt_Bremser
Super User

@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,_)";

 

View solution in original post

21 REPLIES 21
Peter_C
Rhodochrosite | Level 12
All about timing
Compile time : is macro time
Run time : observation time
Kurt_Bremser
Super User

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.

SASKiwi
PROC Star

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;

 

Astounding
PROC Star

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.

 

gyambqt
Obsidian | Level 7

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.

gyambqt
Obsidian | Level 7

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

thanks

Astounding
PROC Star

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.

gyambqt
Obsidian | Level 7

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?

Kurt_Bremser
Super User

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?

Astounding
PROC Star

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.

gyambqt
Obsidian | Level 7

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,_)||"'";

Kurt_Bremser
Super User

@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,_)";

 

Peter_C
Rhodochrosite | Level 12
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()

sas-innovate-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

Register now!

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
  • 21 replies
  • 1302 views
  • 1 like
  • 5 in conversation