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

Hello,

 

Question:

Why doesn't the code below resolve to the value of x?

 

Background:

I would like to be able to reference a list of names, then reference their values.

In a way, I am trying to use the macro variable like a dictionary where the list of names x, y, z are the keys and the values assigned to them are the values in the dict.

 

SAS CODE:

%LET x = 1;
%LET y = 2;
%LET z = 3;

%LET var_list = x~y~z;
%LET first_val = %SCAN(&var_list,1,'~');

%PUT &first_val;
%PUT &&first_val;

%LET first_val = %str(&)%SCAN(&var_list,1,'~');

%PUT &first_val;
%PUT &&first_val;

 

SAS LOG:

8343 %LET x = 1;
8344 %LET y = 2;
8345 %LET z = 3;
8346
8347 %LET var_list = x~y~z;
8348 %LET first_val = %SCAN(&var_list,1,'~');
8349
8350 %PUT &first_val;
x
8351 %PUT &&first_val;
x
8352
8353 %LET first_val = %str(&)%SCAN(&var_list,1,'~');
8354
8355 %PUT &first_val;
&x
8356 %PUT &&first_val;
&x

 

Thank you in advance for your help!

1 ACCEPTED SOLUTION

Accepted Solutions
Quentin
Super User

Hi,

 

You need one more ampersand:

1
2    %LET x = 1;
3    %LET y = 2;
4    %LET z = 3;
5
6    %LET var_list = x~y~z;
7
8    %LET first_val = %SCAN(&var_list,1,~);
9    %PUT &&&first_val;
1
10
11   %LET second_val = %SCAN(&var_list,2,~);
12   %PUT &&&second_val;
2

When there are multiple ampersands, two ampersands resolve to one, and then triggers the macro processor to re-scan it. So the resolution is:

 

&&&first_val
&x     <-- first two && resolve to &, &first_val resolves to x
1      <-- &x resolves to 1

If you want to read up on it, you can google for "multiple ampersands" or "indirect macro variable reference".

 

There are of course alternatives for storing this sort of look up in SAS.  For something simple like this (one value for each key), often a format is enough.  Or if you have multiple values per key, you might want to store the dictionary in a SAS dataset, and then load it into a hash table for lookups.

BASUG is hosting free webinars ! Check out our recordings of past webinars: https://www.basug.org/videos. Be sure to subscribe to our email list for notification of future BASUG events.

View solution in original post

2 REPLIES 2
Quentin
Super User

Hi,

 

You need one more ampersand:

1
2    %LET x = 1;
3    %LET y = 2;
4    %LET z = 3;
5
6    %LET var_list = x~y~z;
7
8    %LET first_val = %SCAN(&var_list,1,~);
9    %PUT &&&first_val;
1
10
11   %LET second_val = %SCAN(&var_list,2,~);
12   %PUT &&&second_val;
2

When there are multiple ampersands, two ampersands resolve to one, and then triggers the macro processor to re-scan it. So the resolution is:

 

&&&first_val
&x     <-- first two && resolve to &, &first_val resolves to x
1      <-- &x resolves to 1

If you want to read up on it, you can google for "multiple ampersands" or "indirect macro variable reference".

 

There are of course alternatives for storing this sort of look up in SAS.  For something simple like this (one value for each key), often a format is enough.  Or if you have multiple values per key, you might want to store the dictionary in a SAS dataset, and then load it into a hash table for lookups.

BASUG is hosting free webinars ! Check out our recordings of past webinars: https://www.basug.org/videos. Be sure to subscribe to our email list for notification of future BASUG events.
Tom
Super User Tom
Super User

Not sure the usefulness of this, but the basic idea is simple. Pull the name out of the list into a macro variable.  Then use triple & to evaluate the value of macro variable whose name is stored in that macro variable.

%let x = 1;
%let y = 2;
%let z = 3;
%let var_list = x~y~z;
%let name=%scan(&var_list,1,~);
%put &name=&&&name;

PS Do not include single quotes in the list of characters to use as delimiters when scanning the list of names. It doesn't matter in this case as none of the values could contain a single quote since they are names of macro variables.

 

Results:

1540  %let name=%scan(&var_list,1,~);
1541  %put &name=&&&name;
x=1

The SYMBOLGEN option will help show how it works.

1542  options symbolgen;
1543  %put &name=&&&name;
SYMBOLGEN:  Macro variable NAME resolves to x
SYMBOLGEN:  && resolves to &.
SYMBOLGEN:  Macro variable NAME resolves to x
SYMBOLGEN:  Macro variable X resolves to 1
x=1

 

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
  • 2 replies
  • 1016 views
  • 4 likes
  • 3 in conversation