Is there a shorthand in SAS for defining a sequence of letters in an array?
Many languages possess a mechanism for doing so easily and I imagine SAS does too, although I'm unable to find a reference for it.
For instance, in R I could do
> x <- letters[1:4]
> x
[1] "a" "b" "c" "d"
In Python, one way is
>>> import string
>>> list(string.ascii_lowercase[:4])
['a', 'b', 'c', 'd']
In SAS, I currently am having to list the letters explicitly,
data _null_;
array letters (4) $ _temporary_ ('a', 'b', 'c', 'd');
do i = 1 to hbound(letters);
put letters(i);
end;
run;
To initialize a static multidimensional array, use the ARRAY or DECLARE statement to list values for the first row of the array, followed by values for the second row, and so on.
A character array is a sequence of characters, just as a numeric array is a sequence of numbers. A typical use is to store a short piece of text as a row of characters in a character vector.
Array range notation is a shorthand notation to facilitate passing of array variables to built-in, internal and external Functions and Procedures. A range of array variables can be indicated by separating the first array index value from the last index value by two decimal points.
A SAS array is a convenient way of temporarily identifying a group of variables for processing within a data step. Once the array has been defined the programmer is now able to perform the same tasks for a series of related variables, the array elements.
You can use the COLLATE()
to generate a string of single byte characters. If you don't know the ASCII code for the start of the block of characters you want then use the RANK()
function.
So if you only want four characters start from 'a' you could do it this way.
length str $4 ;
str = collate(rank('a'));
Or you could also use the optional second parameter to COLLATE()
to specify how many characters you want.
length str $4 ;
str = collate(rank('a'),rank('a')+vlength(str)-1);
There is no need for an "array", just use a variable.
data _null_;
length str $4 ;
str = collate(rank('a'));
do i=1 to vlength(str);
ch = char(str,i);
put i= ch= :$quote. ;
end;
run;
Result:
i=1 ch="a"
i=2 ch="b"
i=3 ch="c"
i=4 ch="d"
Not that I'm aware of, but it is trivial to write a macro to do that.
%macro letter_sequence(start=1,end=, lower=1);
%local i addon;
%if &lower=1 %then %let addon=96;
%else %let addon=64;
%do i = &start+&addon. %to &end.+&addon.;
"%sysfunc(byte(&i.))"
%end;
%mend letter_sequence;
data test;
array x[4] $ (%letter_sequence(end=4));
put x[2]=;
run;
Another option is to use the collate
function and the call pokelong
routine:
/*Upper case*/
data _null_;
array a[26] $1;
call pokelong(collate(65,65+25),addrlong(a1),26);
put _All_;
run;
/*Lower case*/
data _null_;
array a[26] $1;
call pokelong(collate(97,97+25),addrlong(a1),26);
put _All_;
run;
This bypasses all the usual mechanisms for assigning values for individual variables and takes advantage of the default memory layout used by SAS for character arrays, copying the whole alphabet in one go starting at the address for the first element.
N.B. call pokelong
might not be available in some locked-down SAS environments, e.g. SAS University Edition. Also, this might not work properly with temporary arrays in SAS 9.1.3 or earlier on some platforms.
I think this is the only way to do this in SAS without either hard-coding your letters or writing some sort of loop.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With