BookmarkSubscribeRSS Feed
rodrigobarg
Fluorite | Level 6

Hi, sorry for the utlranoob question but, if I have a variable %let VARIABLE = (1, 2, 3, 4), how do I access the value 2? Variable[2] doesn't work...

6 REPLIES 6
novinosrin
Tourmaline | Level 20

Are you asking for this?

 


%let VARIABLE = 1, 2, 3, 4;

%let want =%scan(%superq(variable),2,%str(,));
%put &=want;

202 %let VARIABLE = 1, 2, 3, 4;
203
204 %let want =%scan(%superq(variable),2,%str(,));
205 %put &=want;
WANT=2

 

Tom
Super User Tom
Super User

The first thing to notice is that you don't have a variable at all. Instead you have a macro variable. 

The SAS macro processor is a tool for generating code. So everything to it is text. Although it does have some functions that can treat the text as integer numbers , %EVAL(), or floating point numbers, %SYSEVALF().

 

A macro variable like that:

 

%let VARIABLE = (1, 2, 3, 4) ;

Might be useful in generating some SAS code like:

data want ;
  set have;
  where codevar in &variable;
run;

Which will generate this WHERE statement for SAS to interpret and run.

where codevar in (1, 2, 3, 4);

Commas in general are a pain to use in macro code since they are used as delimiter in macro function calls and between parameters. But adding the parentheses into the value does make it easier to use since the parentheses will protect the commas from being seen as delimiters.  Also not that since the %SCAN() function can use multiple delimiters you use do the same thing to pass both comma and and the parentheses as the value of the third parameter to the %SCAN() function.

 

%let third=%scan(&variable,3,(,));

 

But it is usually easier create a macro variable with a list of values without the comma and parentheses.

%let VARIABLE = 1 2 3 4 ;

It is then still easy to use as before, you just need to add the parentheses back.  Note that SAS does NOT need commas in the list of values used by the IN operator.

where codevar in (&variable);

But it is way easier to parse out the individual values.

%let third=%scan(&variable,3,%str( ));

 

 

Reeza
Super User

SAS doesn't have the concept of lists or arrays that other languages do. If you really want that style of programming you're best bet is to work in IML, otherwise, you likely should be learning how SAS works - the first e-course is free. 

 

In general, SAS operates pretty differently than other programming languages due to the line by line processing of data, but that also means your code that works on 10 records will work on 10 million records within a data step. 

 

If you can generalize your problem, we can recommend the optimal solutions within SAS. 

 


@rodrigobarg wrote:

Hi, sorry for the utlranoob question but, if I have a variable %let VARIABLE = (1, 2, 3, 4), how do I access the value 2? Variable[2] doesn't work...


 

ballardw
Super User

Why does that variable contain parentheses? Commas?

You will find that except for very specific purposes punctuation and special characters add complexity when dealing with macro variables.

 

%let variable = 1 2 3 4 ;

%let var2 = %scan(&variable. , 2);

%put var2= &var2.

Which will not work with the commas.

 

Commas are the delimiter for macro functions and can cause a lot of headaches.

 

Astounding
PROC Star

Presumably if you are thinking about using SAS, you have some understanding of a DATA step.  Here is how you would refer to your list elements within a DATA step:

 

%let variable = 1 2 3 4 5;

data play;
   array v {%sysfunc(countw(&variable))} _temporary_ (&variable);
   .... more DATA step code .....

Now within that DATA step you can refer to the first element as v[1] (or v{1} or v(1) or v{abc} where the variable ABC has a value of 1).

 

The COUNTW function determines that the number of elements is 5.  If you refer to v{7} you will get an error message about an array subscript being out of range.

ScottBass
Rhodochrosite | Level 12

As folks have said, the SAS macro processor is just a tool for generating SAS code.  It controls the code that gets sent to the SAS compiler.

 

I like to think of it as analogous to compiler directives in other languages, such as C: 

https://www.cs.auckland.ac.nz/references/unix/digital/AQTLTBTE/DOCU_078.HTM

 

The analogy isn't exact, but works for me to help me understand SAS macro processing.  YMMV.

 

As others have also said, commas in your macro variables can be problematic, especially if that macro variable is passed to another macro or macro function.  This is because macro is just text, and commas are delimiters for macro parameters.

 

I also don't like to include syntax in my macro variables, i.e. commas, parentheses, quotes, etc.  Instead, I like to only include the data in the macro variable, then "inject" the syntax at the point where the macro variable is referenced.

 

An example:

 

* a list of names ;
* notice the list is space separated, not comma separated ;
%let list = Alfred Henry John Philip;

* it is easy to parse this list ;
%macro test;
   %let i=1;
   %let word=%scan(&list,&i,%str( ));
   %do %while (&word ne );
      %put &=word;
      %let i=%eval(&i+1);
      %let word=%scan(&list,&i,%str( ));
   %end;
%mend;
%test

* an alternative is to use my %loop macro, ;
* which encapsulates the list parsing and calls a child macro ;
* for every token in the list ;
%macro code;
   %put &=word;
%mend;
%loop(&list)

* use the seplist macro to "inject" syntax when the list is referenced ;
%put %seplist(&list);
%put %seplist(&list,nest=q);
%put %seplist(&list,nest=qq);
%put %seplist(&list,dlm=|);

* so, injecting the syntax at "runtime" ;
data class_subset;
   set sashelp.class;
   where name in (%seplist(&list,nest=qq));
run;

* for RBDMS's, sometimes you need a macro variable to be single quoted ;
%let foo=bar;
%put %squote(&foo);

* or you could also use %seplist for a single token only ;
%put %seplist(&foo,nest=q);

Credit for the %squote macro goes to @Tom , see the macro header for details.

 

https://github.com/scottbass/SAS/blob/master/Macro/loop.sas

https://github.com/scottbass/SAS/blob/master/Macro/seplist.sas

https://github.com/scottbass/SAS/blob/master/Macro/squote.sas

https://github.com/scottbass/SAS/blob/master/Macro/parmv.sas


Please post your question as a self-contained data step in the form of "have" (source) and "want" (desired results).
I won't contribute to your post if I can't cut-and-paste your syntactically correct code into SAS.

hackathon24-white-horiz.png

2025 SAS Hackathon: There is still time!

Good news: We've extended SAS Hackathon registration until Sept. 12, so you still have time to be part of our biggest event yet – our five-year anniversary!

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.

SAS Training: Just a Click Away

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

Browse our catalog!

Discussion stats
  • 6 replies
  • 1569 views
  • 3 likes
  • 7 in conversation