the - SAS-Definir una matriz de letras
sas vuelos (4)
¿Hay una abreviatura en SAS para definir una secuencia de letras en una matriz?
Muchos idiomas poseen un mecanismo para hacerlo fácilmente e imagino que SAS también lo hace, aunque no puedo encontrar una referencia para ello.
Por ejemplo, en RI podría hacer
> x <- letters[1:4]
> x
[1] "a" "b" "c" "d"
En Python, una forma es
>>> import string
>>> list(string.ascii_lowercase[:4])
[''a'', ''b'', ''c'', ''d'']
En SAS, actualmente tengo que listar las letras explícitamente,
data _null_;
array letters (4) $ _temporary_ (''a'', ''b'', ''c'', ''d'');
do i = 1 to hbound(letters);
put letters(i);
end;
run;
No es que yo sepa, pero es trivial escribir una macro para hacer eso.
%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;
Otra opción es usar la función de collate
y la rutina 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;
Esto omite todos los mecanismos habituales para asignar valores a variables individuales y aprovecha el diseño de memoria predeterminado utilizado por SAS para las matrices de caracteres, copiando todo el alfabeto de una vez a partir de la dirección del primer elemento.
NB call pokelong
podría no estar disponible en algunos entornos SAS bloqueados, por ejemplo, SAS University Edition. Además, es posible que esto no funcione correctamente con arreglos temporales en SAS 9.1.3 o anterior en algunas plataformas.
Creo que esta es la única forma de hacerlo en SAS sin codificar las letras o escribir algún tipo de ciclo.
Puede usar COLLATE()
para generar una cadena de caracteres de un solo byte. Si no conoce el código ASCII para el inicio del bloque de caracteres que desea, utilice la función RANK()
.
Entonces, si solo quieres cuatro caracteres que comiencen desde ''a'', podrías hacerlo de esta manera.
length str $4 ;
str = collate(rank(''a''));
O también podría usar el segundo parámetro opcional para COLLATE()
para especificar cuántos caracteres desea.
length str $4 ;
str = collate(rank(''a''),rank(''a'')+vlength(str)-1);
No hay necesidad de una "matriz", solo usa una 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;
Resultado:
i=1 ch="a"
i=2 ch="b"
i=3 ch="c"
i=4 ch="d"
Puede usar una combinación de la función de rank
(que convierte un carácter a su valor ascii) y la función de byte
(que se convierte de regreso).
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;