SAS: Uso de macrovariables

Las macrovariables de SAS son las variables que en SAS Base se utilizan, como en otros lenguajes de programación para almacenar ciertos valores. En SAS hay una particularidad que hace que su manejo sea distinto que en otros lenguajes que seguramente ya conocemos, y es que las variables de SAS no tienen formato. Así que cuando almacenamos un número, un texto o una fecha en una macrovariable se almacena exactamente ese contenido sin alteración.

Esta particularidad tiene dos consecuencias: debemos saber tratar cada variables en función del tipo de valor que almacena cuando queremos compararlo con otros valores para comparar cosas del mismo tipo. Y por otro lado no podemos asignar el resultado de una función a una macrovariable directamente.

Manejar macrovariables con números es fácil porque se pueden comparar directamente con números o con el contenidos de campos numéricos porque los números no se expresan con ningún formato especial:

%let a = 1;

data tabla1;
    numero = 1;
    if numero = &a then valida1 = 1;
    if &a = 1 then valida2 = 1;
run;

En el caso de los textos, estos tienen que ir entre comillas (dobles o simples da igual) y hay que tener en cuenta eso cuando utilicemos variables con SAS. Además hay que tener en cuenta que una macrovariable se resuelve si va sin comillas o dentro de comillas dobles, pero no lo hace si va dentro de comillas simples. Veremos esto primero porque puede generar algunas confusiones:

%let texto = Ojo por ojo y el mundo acabará ciego;
ComandoResultado
%put &texto;Ojo por ojo y el mundo acabará ciego
%put «&texto»;«Ojo por ojo y el mundo acabará ciego»
%put ‘&texto’;‘&texto’

Como veis el hecho de incluir las dobles comillas o no afecta al contenido de la macrovariable y eso hay que tenerlo en cuenta al usar la macrovariable y compararla con otro valor. Por ejemplo, tomemos estas variables:

%let ciudad1 = Madrid;
%let ciudad2 = "Barcelona";
%let ciudad3 = 'Sevilla';
OperaciónResultado
&ciudad1 = «Madrid»FALSEciudad1 contiene Madrid, y así escrito SAS lo confunde con el nombre de un campo de una tabla.
&ciudad1 = MadridTRUEInesperado resultado. Tanto el contenido de la macrovariable como el valor con el que se compara están sin comillas. SAS confunde eso con el nombre de un campo y está un campo consigo mismo. Si esta comparación estuviera en un if dentro de un paso data, se crearía el campo Madrid a nulo en la tabla de salida y esta comparación sería cierta.
«&ciudad2» = «Barcelona»TRUEEsto es correcto ambas partes de la igualdad están entre comillas dobles.
«&ciudad2» = ‘Barcelona’TRUEEste caso también es correcto porque un texto debe estar delimitado entre comillas, da igual si son simples o dobles.
‘&ciudad2’ = «Barcelona»FALSELo contrario no funciona porque no se resuelve el contenido de una macrovariable dentro de comillas simples: estaría comparando el nombre de la macrovariable con la cadena de texto.
&ciudad3 = «Sevilla»TRUELa variable ciudad3 contiene una cadena entre comillas simples lo que es comparable a un valor de texto. Este caso parece muy parecido al anterior ya que el contenido de la variable está entre comillas simples, pero nótese que no es lo mismo poner las comillas simples conteniendo la variable que si está dentro de la variable.

Con todo lo anterior, lo que os recomiendo es que utilicéis siempre las macrovariables de texto de la misma manera en vuestro código de forma general para no confundiros en como debéis expresar las igualdades. Por ejemplo, esta forma de hacerlo es una de las válidas:

%let nombre= Jose Luis;
data salida1;
    if "&nombre" = "Jose Luis" then sexo = 'H';
run;

Con las fechas pasa algo similar a lo anterior teniendo en cuenta que las fechas se indican entre comillas (dobles o simples) con una -d- detrás si es fecha o con -dt- si es una fecha-hora. Para trabajar con fechas recomiendo asignar a la macrovariable un valor como si estuviera en formato date9., pero sin las comas ni la -d-.

%let fecha= 15may2021;
data salida2;
    if '1jan2021'd <= "&fecha"d <= "31dec2021"d then anyo = 2021;
run;

De todo lo anterior se desprende que una macrovariable guarda todo lo que se le asigna sin interpretarlo y sin tener en cuenta su formato. Por esa misma razón una macrovariable puede contener también una función o un pequeño trozo de código que puede construirse y hacerse ejecutar en tiempo de ejecución… aunque esto lo veremos en otro momento.