Download presentation
Presentation is loading. Please wait.
1
3 Iterative Processing
2
Execute macro language statements iteratively
Execute macro language statements iteratively. Generate SAS code iteratively.
3
Simple Loops %DO index-variable=start %TO stop <%BY increment>;
Macro applications might require iterative processing. The iterative %DO statement can execute macro language statements and generate SAS code. %DO index-variable=start %TO stop <%BY increment>; text %END;
4
Simple Loops %DO and %END statements are valid only inside a macro definition. index-variable is a macro variable. index-variable is created in the local symbol table if it does not already exist in another symbol table. start, stop, and increment values can be any valid macro expressions that resolve to integers. The %BY clause is optional. (The default increment is 1.)
5
Simple Loops text can be any of: constant text macro variables or expressions macro statements macro calls
6
The SYMPUTX Routine (Review)
Example: Create a numbered series of macro variables. data _null_; set orion.country end=no_more; call symputx('Country'||left(_n_),country_name); if no_more then call symputx('numrows',_n_); run; proc sql; select name from dictionary.macros where scope="GLOBAL"; quit; Note the additional macro variable NUMROWS, based on the last value of _N_. SAS programmers everywhere propagate a great myth, telling each other that _N_ is an observation number. So the poor SAS instructor must once again remind students that the DATA step is an implied loop and that automatic DATA step variable _N_ is the DATA step's loop counter. (It may or may not correspond to an input or output observation number, depending on the program.) Here again, we see %put _user_; lists macro variables in no particular order.
7
data _null_; set orion.country end=no_more; call symputx('Country'||left(_n_),country_name); if no_more then call symputx('numrows',_n_); run; proc sql; select name, value from dictionary.macros where scope="GLOBAL" and upcase(name) contains "COUNTRY"; quit; describe table dictionary.macros;
8
Simple Loops %macro putloop; %do i=1 %to &numrows;
%put Country&i is &&country&i; %end; %mend putloop; %putloop Using a macro loop, we can guarantee that these numbered macro variables are listed in numerical order.
9
Example: Iteratively generate complete SAS steps.
10
%let path=c:\users\dlm1\dropbox\sas\sasdata;
%macro readraw(first=2003,last=2007); %do year=&first %to &last; data year&year; infile "&path\mac1\orders&year..dat"; input order_ID order_type order_date : date9.; run; %end; %mend readraw; options mlogic mprint; %readraw(first=2004,last=2006) options nomlogic nomprint; This loop will iterate three times.
11
Generating Data-Dependent Code
Example: Create a separate data set for each value of a selected variable in a selected data set. %split(data=orion.customer, var=country)
12
Step 1: Store unique data values into macro variables.
%macro split (data=, var=); proc sort data=&data(keep=&var) out=values nodupkey; by &var; run; data _null_; set values end=last; call symputx('site'||left(_n_),&var); if last then call symputx('count',_n_); %put _local_; %mend split; %split(data=orion.customer, var=country) This is the first half of the program. %put _local_; lists the local symbol table. This statement is only for diagnostic purposes.
13
Generating Data-Dependent Code
Step 2: Use loops to generate the DATA step. %macro split (data=, var=); proc sort data=&data(keep=&var) out=values nodupkey; by &var; run; data _null_; set values end=last; call symputx('site'||left(_n_),&var); if last then call symputx('count',_n_); data %do i=1 %to &count; &&site&i %end; ; set &data; select(&var); when("&&site&i") output &&site&i; otherwise; end; %mend split; %split(data=orion.customer, var=country) The program is completed here. The red box highlights the portion of the program that has been added. The semi-colon on a line by itself ends the DATA statement.
14
Example: Print all data sets in a SAS data library
Example: Print all data sets in a SAS data library. Step 1: Store data set names into macro variables. %macro printlib(lib=WORK); %let lib=%upcase(&lib); data _null_; set sashelp.vstabvw end=final; where libname="&lib"; call symputx('dsn'||left(_n_),memname); if final then call symputx('totaldsn',_n_); run; %put _local_; %mend printlib; %printlib(lib=orion) This cool macro accepts a single parameter; a library name, which defaults to WORK. The user does not need to know how many datasets are in the library or the dataset names. It's all automated. Just call the macro! This is the first half of the program. %put _local_; lists the local symbol table. This statement is only for diagnostic purposes.
15
Generating Data-Dependent Code
Step 2: Use a macro loop to print every data set in the library. %macro printlib(lib=WORK,obs=5); %let lib=%upcase(&lib); data _null_; set sashelp.vstabvw end=final; where libname="&lib"; call symputx('dsn'||left(_n_),memname); if final then call symputx('totaldsn',_n_); run; %do i=1 %to &totaldsn; proc print data=&lib..&&dsn&i(obs=&obs); title "&lib..&&dsn&i Data Set"; %end; %mend printlib; %printlib(lib=orion) The program is completed here. The red box highlights the portion of the program that has been added.
16
Conditional Iteration
You can perform conditional iteration in macros with %DO %WHILE and %DO %UNTIL statements. General form of the %DO %WHILE statement: A %DO %WHILE loop: evaluates expression at the top of the loop before the loop executes executes repetitively while expression is true %DO %WHILE(expression); text %END; This section is self-study only due to time concerns. If you have the time, go for it!
17
Conditional Iteration
General form of the %DO %UNTIL statement: expression can be any valid macro expression. A %DO %UNTIL loop does the following: evaluates expression at the bottom of the loop after the loop executes executes repetitively until expression is true executes at least once %DO %UNTIL(expression); text %END;
18
Conditional Iteration
Example: Generate a conditional number of program steps, based on a parameter value. %macro stats(datasets); %let i=1; %let dsn=%scan(&datasets,1); %do %while(&dsn ne ); title "ORION.%upcase(&dsn)"; proc means data=orion.&dsn n min mean max; run; %let i=%eval(&i+1); %let dsn=%scan(&datasets,&i); %end; title; %mend stats; %stats(staff specialsals country) The single parameter, DATASETS, is a list of dataset names delimited by spaces. The macro issues a proc means step for each listed dataset. There is no limit to the number of datasets. Dataset names are not validated, so potential for errors exists.
19
Example: Modify the previous example to validate data set names.
%macro stats(datasets); %let i=1; %do %until(&dsn= ); %let dsn=%scan(&datasets,&i); %if &dsn= %then %put NOTE: Processing completed.; %else %if %sysfunc(exist(orion.&dsn)) %then %do; title "ORION.%upcase(&dsn)"; proc means data=orion.&dsn n min mean max; run; %end; %else %put ERROR: No &dsn dataset in ORION library.; %let i=%eval(&i+1); %mend stats; %stats(discount music orders) This version of the previous application uses DO UNTIL instead of DO WHILE and validates dataset names with the EXIST function. A Color-coded error message is issued for non-existent datasets. See log on next slide. The application also issues a color-coded Processing completed note.
20
Make multiple copies of a dataset
data tmp; do i=1 to 5; output; end; run; data tmp1; set tmp tmp; proc print data=tmp1 noobs;
21
%macro mkcopies(reps,newdata,copydata);
data &newdata; set %do i=1 %to &reps; ©data %end; ; run; %mend mkcopies; options mprint; %mkcopies(2,tmp2,tmp); proc print data=tmp2; options nomprint;
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.