• No se han encontrado resultados

Paper MACROS EN SAS JUAN RADHAMES GÓMEZ MARTÍNEZ

N/A
N/A
Protected

Academic year: 2021

Share "Paper MACROS EN SAS JUAN RADHAMES GÓMEZ MARTÍNEZ"

Copied!
11
0
0

Texto completo

(1)

Paper 2014-002

MACROS EN SAS

JUAN RADHAMES

G

ÓMEZ

M

ARTÍNEZ

R

ESUMEN

(A

BSTRACT

)

El macro lenguaje de SAS es una de las herramientas más poderosas que provee SAS. Este lenguaje si es utilizado de una manera correcta nos permite la realización de una serie de actividades que de otra forma implicarían la escritura de un sinnúmero de líneas de código y sobre todo la eficientización de procesos.

En este documento presentamos el concepto de macros y macro variables, como pueden ser utilizadas, así como también dos ejemplos puntuales de cómo los macros nos pueden ayudar en términos de eficiencia y estandarización.

Al concluir este documento pretendemos que usted conozca la diferencia entre una macro variable y un macro y la manera en que estos pueden interactuar para la generación de un programa eficiente.

C

ONCEPTOS

Macros, macro variables.

MACROS

EN

SAS

CONCEPTO DE MACRO

Una macro (del griego μακρο, makro, que significa ‘grande’) - es una abreviatura de macroinstrucción- y aparte es una serie de instrucciones que se almacenan para que se puedan ejecutar de manera secuencial mediante una sola llamada u orden de ejecución. Dicho de otra manera, una macroinstrucción es una instrucción compleja, formada por otras instrucciones más sencillas. Esto permite la automatización de tareas repetitivas. (Wikipedia).

Más propiamente dentro del lenguaje, SAS provee una herramienta para la utilización de macros que permite reducir la cantidad de texto que debemos escribir para realizar tareas comunes. El procesador de macros lee el macro lenguaje y transforma el código ya revisado en un programa de SAS.

En SAS existen dos formas en las que nos referimos a los macros:

Las macro variables, las cuales se pueden referenciar bajo la siguiente nomenclatura &name. Y los macros que pueden ser referenciados utilizando la nomenclatura %name.

(2)

MACRO VARIABLES

Las macro variables se utilizan en SAS para reemplazar cadenas de texto dentro del código. La manera mas simple de definir una macro variable es utilizando la sentencia %LET.

%LET texto = Esto es una prueba %PUT el valor de texto es &texto.

En este ejemplo al hacer referencia a la variable texto, lo que se imprime en el log de SAS es: el valor de texto es Esto es una prueba.

Otra manera de crear macro variables dentro de un data step es utilizando la expresión SYMPUT. Al llamar a esta expresión debemos pasar dos parámetros, el primero el nombre la macro variable que queremos crear y asignar un valor y el segundo parámetro es el valor a asignar.

Es bueno destacar que el valor de la macro variable solo estará disponible luego de ejecutado el data step. DATA _NULL_;

Fecha = today();

Call symput(“fecha”, fecha); RUN;

MACROS

Los macros son programas compilados que pueden ser llamados dentro de un programa de SAS o desde la línea de comandos de SAS. Al igual que con las macro variables, los macros se utilizan para generar texto. Sin embargo los macros poseen cualidades adicionales como:

Los macros pueden tener sentencias de programación que nos permiten indicar cómo y cuando el texto va a ser generado.

Los macros aceptan parámetros. Estos nos permite generar macros genéricos que pueden tener múltiples usos.

Para que un macro pueda ser compilado, se debe generar una definición de macro. La forma general para esta definición es la siguiente:

(3)

%MACRO nombre_macro; <texto_macro>

%MEND <nombre_macro>;

Donde nombre_macro es el nombre único de SAS que identifica el macro y texto_macro es cualquier combinación de sentencias, llamadas a macros, expresiones o constantes de texto.

%MACRO primer_macro; PROC PRINT DATA=SALES;

TITLE1 “TESTING MY FIRST MACRO”; %MEND primer_macro;

%primer_macro;

POR QUE UTILIZAR MACROS

La utilización de macros provee un sinnúmero de ventajas dentro de las que podemos mencionar; Generación automática de código SAS.

Reducen el esfuerzo requerido para leer y escribir código SAS. Reutilización de código.

Permite la utilización de parámetros.

Permiten controlar el flujo de ejecución de un programa, dentro de un macro podemos utilizar sentencias iterativas y de condición que abarcan a más de un data step.

Eficientizacion de Código.

EJEMPLOS DE MACROS EN SAS

Reporte personalizado a una lista de correos.

%macro reporte(codigo,nombre,email); %ventas(&codigo.);

%let mailTo = "&email.";

%let mailFrom = "[email protected]"; %let mailCC = "[email protected]";

(4)

filename mymail EMAIL from = &mailFrom.

To = (&mailTo.) CC = &mailCC.

Subject = "Reporte" ct ='text/html' ;

ods html body=mymail style=seaside rs=none ;

ods html text='<div align="left">Buenos Dias </div>'; ods html text="<div>Sres. &nombre. </div>";

ods html text='<br>'; ods html text='<br>';

ods html text='<div align="left">Distinguido Cliente, </div>'; ods html text='<br>';

ods html text="<div align=>En cumplimiento los acuerdos realizados, anexo los reportes de ventas al <b> &mesano. </b>.

ods html text="<div align=>Cualquier duda o sugerencia acerca del Reporte por favor canalícenla a través de su representante</div>";

ods html text="<br><br>";

ods html text="<div align=>Saludos!</div>"; ods html text="<br><br>";

proc report data=sales HEADLINE HEADSKIP nowd missing split="\"

style(header)=[foreground=white background=crimson bordercolor=black] style(column)=[bordercolor=black ];

columns nombre (ventas, MES_BO); DEFINE nombre / GROUP 'Cliente'; DEFINE Mes / across 'Mes';

define ventas / Ventas Brutas' format=comma10.2; title1 '<b>Ventas Brutas </b>';

run; ods html close; quit; %mend; DATA WORK.correo_clientes; LENGTH Codigo $ 4 Nombre $ 64 Estatus $ 8 email $ 105 ; FORMAT

(5)

codigo $CHAR4. Nombre $CHAR64. Estatus $CHAR8. email $CHAR105. ; INFORMAT codigo $CHAR4. nombre $CHAR64. Estatus $CHAR8. email $CHAR105. ; INFILE &ruta..correo_clientes.txt" DELIMITER='09'x LRECL=400 MISSOVER DSD firstobs=2; INPUT Codigo $ Nombre $ Estatus $ email $ RUN; proc sql;

select count(codigo) into :cantidadclientes

from correo_clientes(where=(^ missing(email))); %let cantidadClientes = & cantidadclientes;

quit; proc sql;

select codigo, nombre_dealer, email

into :codigo1 - :codigo& cantidadclientes, :nombre1 - :nombre& cantidadclientes., :email1 - :email& cantidadclientes.

from correo_clientes (where=(^ missing(email))); quit;

%macro enviaEmail;

%do i=1 %to & cantidadclientes; %let codigo = &&codigo&i; %let nombre = &&nombre&i; %let email = &&email&i;

%reporte(&codigo.,&nombre.,&email.); %end;

%mend;

(6)

Ejemplo de Eficiencia de Código

%let enero2013 = work.SALE_EST_JAN2013; %let febrero2013 = work.SALE_EST_FEB2013; %let marzo2013 = work.SALE_EST_MAR2013; %let abril2013 = work.SALE_EST_APR2013; %let mayo2013 = work.SALE_EST_MAY2013; %let junio2013 = work.SALE_EST_JUN2013; %let julio2013 = work.SALE_EST_JUL2013; %let agosto2013 = work.SALE_EST_AUG2013; %let septiembre2013 = work.SALE_EST_SEP2013; %let octubre2013 = work.SALE_EST_OCT2013; %let noviembre2013 = work.SALE_EST_NOV2013; %let diciembre2013 = work.SALE_EST_DEC2013; %let enero2014 = work.SALE_EST_JAN2014; %let febrero2014 = work.SALE_EST_FEB2014; %let marzo2014 = work.SALE_EST_MAR2014; %let Abril2014 = work.SALE_EST_APR2014; %let Mayo2014 = work.SALE_EST_MAY2014; %let junio2014 = work.SALE_EST_JUN2014; %let julio2014 = work.SALE_EST_JUL2014;

data resultado; set ventas; run;

proc sql noprint;

create table estatus_enero2013 as

select a.*, b.sale_status as estatus_enero2013

from resultado a

left join &enero2013. b on a.cuenta = b.cuenta and a.producto = b.producto and a.plan = b.cod_plan; quit;

proc sql noprint;

create table estatus_febrero2013 as

select a.*, b.sale_status as estatus_febrero2013

from estatus_enero2013 a left join &febrero2013. b on a.cuenta = b.cuenta and a.producto = b.producto and a.plan = b.cod_plan; quit;

proc sql noprint;

create table estatus_marzo2013 as

select a.*, b.sale_status as estatus_marzo2013

from estatus_febrero2013 a left join &marzo2013. b on a.cuenta = b.cuenta and a.producto = b.producto

(7)

and a.plan = b.cod_plan; quit;

proc sql noprint;

create table estatus_abril2013 as

select a.*, b.sale_status as estatus_abril2013

from estatus_marzo2013 a left join &abril2013. b on a.cuenta = b.cuenta and a.producto = b.producto and a.plan = b.cod_plan; quit;

proc sql noprint;

create table estatus_mayo2013 as

select a.*, b.sale_status as estatus_mayo2013

from estatus_abril2013 a left join &mayo2013. b on a.cuenta = b.cuenta and a.producto = b.producto and a.plan = b.cod_plan; quit;

proc sql noprint;

create table estatus_junio2013 as

select a.*, b.sale_status as estatus_junio2013

from estatus_mayo2013 a left join &junio2013. b on a.cuenta = b.cuenta and a.producto = b.producto and a.plan = b.cod_plan; quit;

proc sql noprint;

create table estatus_julio2013 as

select a.*, b.sale_status as estatus_julio2013

from estatus_junio2013 a left join &julio2013. b on a.cuenta = b.cuenta and a.producto = b.producto and a.plan = b.cod_plan; quit;

proc sql noprint;

create table estatus_agosto2013 as

select a.*, b.sale_status as estatus_agosto2013

from estatus_julio2013 a left join &agosto2013. b on a.cuenta = b.cuenta and a.producto = b.producto and a.plan = b.cod_plan;

(8)

quit;

proc sql noprint;

create table estatus_septiembre2013 as

select a.*, b.sale_status as estatus_septiembre2013

from estatus_agosto2013 a left join &septiembre2013. b on a.cuenta = b.cuenta

and a.producto = b.producto and a.plan = b.cod_plan; quit;

proc sql noprint;

create table estatus_octubre2013 as

select a.*, b.sale_status as estatus_octubre2013

from estatus_septiembre2013 a left join &octubre2013. b on a.cuenta = b.cuenta and a.producto = b.producto and a.plan = b.cod_plan; quit;

proc sql noprint;

create table estatus_noviembre2013 as

select a.*, b.sale_status as estatus_noviembre2013

from estatus_octubre2013 a left join &noviembre2013. b on a.cuenta = b.cuenta and a.producto = b.producto and a.plan = b.cod_plan; quit;

proc sql noprint;

create table estatus_diciembre2013 as

select a.*, b.sale_status as estatus_diciembre2013

from estatus_noviembre2013 a left join &diciembre2013. b on a.cuenta = b.cuenta and a.producto = b.producto and a.plan = b.cod_plan; quit;

proc sql noprint;

create table estatus_enero2014 as

select a.*, b.sale_status as estatus_enero2014

from estatus_diciembre2013 a left join &enero2014. b on a.cuenta = b.cuenta and a.producto = b.producto and a.plan = b.cod_plan; quit;

(9)

create table estatus_febrero2014 as

select a.*, b.sale_status as estatus_febrero2014

from estatus_enero2014 a left join &febrero2014. b on a.cuenta = b.cuenta and a.producto = b.producto and a.plan = b.cod_plan; quit;

proc sql noprint;

create table estatus_marzo2014 as

select a.*, b.sale_status as estatus_marzo2014

from estatus_febrero2014 a left join &marzo2014. b on a.cuenta = b.cuenta and a.producto = b.producto and a.plan = b.cod_plan; quit;

proc sql noprint;

create table estatus_abril2014 as

select a.*, b.sale_status as estatus_abril2014

from estatus_marzo2014 a left join &Abril2014. b on a.cuenta = b.cuenta and a.producto = b.producto and a.plan = b.cod_plan; quit;

proc sql noprint;

create table estatus_mayo2014 as

select a.*, b.sale_status as estatus_mayo2014

from estatus_abril2014 a left join &Mayo2014. b on a.cuenta = b.cuenta and a.producto = b.producto and a.plan = b.cod_plan; quit;

proc sql noprint;

create table estatus_junio2014 as

select a.*, b.sale_status as estatus_junio2014

from estatus_mayo2014 a left join &junio2014. b on a.cuenta = b.cuenta and a.producto = b.producto and a.plan = b.cod_plan; quit;

(10)

Código Optimizado proc sql;

create table estructura as

select MEMNAME,

input(substr(MEMNAME, 13), monyy7.) AS FECHA format=date9.,

compress(put(input(substr(MEMNAME, 13), monyy7.), espdfmn10.) ||

put(year(input(substr(MEMNAME, 13), monyy7.)), 4.)) AS nombre_var from dictionary.tables

where libname = 'WORK' AND

memname like 'SALE_EST_%'

ORDER BY input(substr(MEMNAME, 13), monyy7.);

quit;

proc sql noprint;

select count(*) INTO :Cant_Tablas

from estructura ; select memname, nombre_var into :tabla1-:tabla%left(&cant_tablas), :nombre1-:nombre%left(&Cant_tablas) from estructura; quit; %macro status ;

%do i=1 %to &cant_tablas; %if &i=1 %then %do;

proc sql noprint;

create table estatus_venta as

select a.*, b.sale_status as estatus_&&nombre&i from resultado a

left join WORK.&&tabla&i b on a.cuenta = b.cuenta and a.producto = b.producto and a.plan = b.cod_plan; quit;

%end;

%else %do;

proc sql noprint;

create table estatus_venta as

select a.*, b.sale_status as estatus_&&nombre&i from estatus_venta a

left join work.&&tabla&i b on a.cuenta = b.cuenta and a.producto = b.producto and a.plan = b.cod_plan; quit;

%end;

%end; %mend status; %status;

(11)

C

ONCLUSIONES

La herramienta de macros que provee SAS es muy poderosa si sabemos dar un uso adecuado de la misma. Puede ayudarnos como lo demuestran los ejemplos a agilizar la ejecución de procesos, así como también a reducir las líneas de código que necesitamos, a través de la reutilización de procesos en los que solo debemos cambiar el o los parámetros de entrada.

Lo importante es que podamos dar un uso adecuado a esta poderosa herramienta que nos provee SAS para hacer nuestro trabajo más llevadero. Es un nuevo lenguaje dentro del lenguaje de SAS, pues presenta sus reglas particulares, y debemos estar preparados para asumir el reto de utilizarlo.

R

EFERENCIAS

Breheny, Patrick. Writing cleaner and more powerful SAS code using macros. Consultado en fecha 01/11/2014 en http://myweb.uiowa.edu/pbreheny/talks/macros.pdf

Cohen, John. A TUTORIAL ON THE SAS MACRO LANGUAGE. AstraZENECA LP.

SAS Institute Inc. 2004. SAS® 9.1 Macro Language: Reference. Cary, NC: SAS Institute Inc.

I

NFORMACIÓN DE

C

ONTACTO

Comentarios y preguntas son apreciados. Contacte al autor Nombre Autor

Juan Radhames Gómez Martínez Claro RD.

INTEC

Email Trabajo: [email protected] Email Personal: [email protected] Redes Sociales

Twitter:radhixz LikedIn:juan-gomez

SAS y cualquier otro nombre de producto o servicio de SAS Institute Inc., son marcas registradas de SAS Institute Inc. Otras marcas y productos son marcar registradas de sus respectivas compañías.

Referencias

Documento similar

If certification of devices under the MDR has not been finalised before expiry of the Directive’s certificate, and where the device does not present an unacceptable risk to health

In addition to the requirements set out in Chapter VII MDR, also other MDR requirements should apply to ‘legacy devices’, provided that those requirements

The notified body that issued the AIMDD or MDD certificate may confirm in writing (after having reviewed manufacturer’s description of the (proposed) change) that the

Para ello, trabajaremos con una colección de cartas redactadas desde allí, impresa en Évora en 1598 y otros documentos jesuitas: el Sumario de las cosas de Japón (1583),

The arguments of the Basic Information Macros macros, as just dis- cussed, are used to define text macros with no parameters; for exam- ple, when you type \title{Web Package}, the

 Tejidos de origen humano o sus derivados que sean inviables o hayan sido transformados en inviables con una función accesoria..  Células de origen humano o sus derivados que

En cada antecedente debe considerarse como mínimo: Autor, Nombre de la Investigación, año de la investigación, objetivo, metodología de la investigación,

En este sentido, puede defenderse que, si la Administración está habilitada normativamente para actuar en una determinada materia mediante actuaciones formales, ejerciendo