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!
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.
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.
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 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!
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.
Ready to level-up your skills? Choose your own adventure.