SAS - define an array of letters

Is there a shorthand in SAS for specifying the sequence of letters in an array?

Many languages ​​have a mechanism for this, and I think SAS does too, although I cannot find a link to it.

For example, 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 have to list letters explicitly,

data _null_;
  array letters (4) $ _temporary_ ('a', 'b', 'c', 'd');
  do i = 1 to hbound(letters);
    put letters(i);
  end;
run;

      

+3


source to share


4 answers


You can use COLLATE()

single-byte characters to generate string. If you don't know the ASCII code for the start of the character block you want, use the function RANK()

.

So, if you wanted four characters to start with "a", you could do it this way.

  length str $4 ;
  str = collate(rank('a'));

      

Or you can 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);

      



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"

      

+2


source


Not that I know, but it is trivial to write a macro for this.



%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;

      

+4


source


Another option is to use a function collate

and a subroutine call pokelong

:

/*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 ​​to individual variables and uses the default memory layout used by SAS for character arrays, copying the entire alphabet in one go, starting at the address for the first element.

NB call pokelong

may not be available in some locked SAS environments, for example. SAS University Edition. Also, it may not work as expected with temporary arrays in SAS 9.1.3 or earlier on some platforms.

I think this is the only way to do it in SAS without hardcoding your emails or writing some kind of loop.

+2


source


You can use a combination of a function rank

(which converts a character to its ascii value) and a function byte

(which converts back the other way).

data _null_;
length seq $51; /* define seq as character variable */
do i = rank('a') to rank('d'); /* loop through ascii values of required letters */
call catx(' ',seq,byte(i)); /* concatenate letters */
end;
put seq; /* print final output */
run;

      

0


source







All Articles