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.

The Boston Area SAS Users Group is hosting free webinars!
Next webinar will be in January 2025. Until then, check out our archives: https://www.basug.org/videos. And be sure to subscribe to our our email list.

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.

The Boston Area SAS Users Group is hosting free webinars!
Next webinar will be in January 2025. Until then, check out our archives: https://www.basug.org/videos. And be sure to subscribe to our our email list.
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

 

SAS Innovate 2025: Save the Date

 SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!

Save the date!

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.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 2 replies
  • 1160 views
  • 4 likes
  • 3 in conversation