Impresionante macro de SAS que nos puede ahorrar picar mucho mucho código. La macro se llama iterlist y la he encontrado en este enlace. Es código SAS muy avanzado:
%macro iterlist(code =, list =);
%*** ASIGNAMOS CADA ELEMENTO DE LA LISTA A UNA MACROVARIABLE INDEXADA &&ITEM&I ;
%let i = 1;
%do %while (%cmpres(%scan(&list., &i.)) ne );
%let item&i. = %cmpres(%scan(&list., &i.));
%let i = %eval(&i. + 1);
%end;
%*** GUARDAMOS EL CONTEO TOTAL ;
%let cntitem = %eval(&i. - 1);
%*** REEMPLAZAMOS EL TOKEN ? CON LOS ELEMENTOS DE LA LISTA ;
%do i = 1 %to &cntitem.;
%let codeprp = %qsysfunc(tranwrd(&code., ?, %nrstr(&&item&i..)));
%unquote(&codeprp.)
%end;
%mend iterlist;
El funcionamiento es muy complejo; destacaría el uso de %qsysfunc. El caso es que nos permite pasar listas de código. Imaginemos que tenemos que hacer la siguiente tarea:
data importes;
drop i j;
array importe(10);
do i = 1 to 20000;
do j = 1 to 10;
importe(j) = ranuni(8) * 1000;
end;
grupo = ranpoi(4, 5);
output;
end;
run;
proc summary data=importes nway;
class grupo;
output out = agr_grupo (drop=_type_ _freq_)
mean(importe1) = media_importe1
mean(importe2) = media_importe2
/* ... hasta 10 ... */
sum(importe1) = suma_importe1
sum(importe2) = suma_importe2;
/* ... hasta 10 ... */
quit;
Necesitamos hacer un PROC SUMMARY de 10 variables y de ellas vamos a calcular media y suma; tendremos que poner SUM y MEAN por tantas variables como correspondan. Estamos repitiendo un código. Pues bien, esta macro nos permite repetir el código dada una lista (en este caso la lista se la pasamos como una macrovariable):
%let lista = importe1 importe2 importe3 importe4 importe5
importe6 importe7 importe8 importe9 importe10;
proc summary data=importes nway;
class grupo;
output out = agr_grupo (drop=_type_ _freq_)
%iterlist(list = &lista., code = %str( mean(?)=media_? ))
%iterlist(list = &lista., code = %str( sum(?)=suma_? ));
quit;
Impresionante. Donde ponemos ? la macro pone los elementos de la lista, y en el parámetro code ponemos el código que se repite con %str. A este que escribe ahora mismo se le han caído los pantalones ante semejante genialidad. Saludos.