SAS: Loop
- 4 minsOverview
1. Data step
Output:
PROC TRANSPOSE vs. Arrays:
2. Macro
Data Step
Output
Syntax:
DATA <data-table-name-new> [keep=/drop=];
DO <index-variable=start> TO <end> [BY increment];
iterated-SAS-statements;
OUTPUT;
END;
RUN;
Missing OUTPUT
will cause SAS to save only the last record.
Example 1
DATA loop;
DO i=2 TO 10 BY 2;
x = i+1;
rep = 1;
OUTPUT;
END;
RUN;
Result:
obs | i | x | rep |
---|---|---|---|
1 | 2 | 3 | 1 |
2 | 4 | 5 | 1 |
3 | 6 | 7 | 1 |
4 | 8 | 9 | 1 |
5 | 10 | 11 | 1 |
Example 2: Nested Do
DO i=1 TO 2;
DO j=1 TO 2;
OUTPUT;
END;
END;
Result:
obs | i | j |
---|---|---|
1 | 1 | 1 |
2 | 1 | 2 |
3 | 2 | 1 |
4 | 2 | 2 |
Same:
DATA doloop;
DO i=1 TO 2;
OUTPUT;
END;
RUN;
DATA doloop;
SET doloop;
DO j=1 TO 2;
OUTPUT;
END;
RUN;
Example 3: Add a sequence to an existing data set (SUM)
DATA doloop;
DO i=1 TO 2;
DO j=1 TO 2;
seq + 1
OUTPUT;
END;
END;
RUN;
seq
will initialize from 0.
Result:
obs | i | j | seq |
---|---|---|---|
1 | 1 | 1 | 1 |
2 | 1 | 2 | 2 |
3 | 2 | 1 | 3 |
4 | 2 | 2 | 4 |
Example 4: Generating random number
DATA random (DROP=i);
CALL STREAMINIT(123);
DO i=1 TO 3;
x = RAND('Normal', 10, 2);
OUTPUT;
END;
RUN;
CALL STREAMINIT(<seed>)
is like set.seed(<seed>)
in R
Macro
Macro Array
Macro Function
Syntax:
- No Parameter
%MACRO <macro-name>;
SAS-statements;
%MEND
- Positional Parameter
%MACRO <macro-name>(<parameter-1>, <parameter-2>);
SAS-statements;
%MEND
%<macro-name>(x, y)
- Key Parameter
%MACRO <macro-name>(<parameter-1>=, <parameter-2>=<default-value-2>);
SAS-statements;
%MEND
%<macro-name>(<parameter-1>=x, <parameter-2>=y)
(1) Conditional Processing
Conditional Macro:
%MACRO <macro-name>;
%IF expression %THEN %<optional-macro>;
%MEND;
Conditional Procedure:
%MACRO <macro-name>;
%IF expression %THEN %DO;
SAS-statement;
%END;
%MEND;
(2) Parameter Validation
%MACRO <macro-name>(<parameter-1>=, <parameter-2>=<default-value-2>);
/* Parameter Validation */
%IF &<parameter-1>= %THEN %DO;
%PUT Param1 is a required argument;
%RETURN;
%END;
SAS-statements;
%MEND;
(3) Iterative Processing
%MACRO <macro-name>(start, stop);
%DO i = &start %TO &stop;
SAS-statements;
%END;
%MEND;
Demo
Demo 1: Conditional
/* Declare Macro name and parameters */
%MACRO mymac(dist, param1=, param2=, n=100, stats=no, plot=no);
/* Parameter Validation */
%IF &dist= %THEN %DO;
%PUT dist is a required argument;
%RETURN;
%END;
%IF ¶m1= %THEN %DO;
%PUT param1 is a required argument;
%RETURN;
%END;
/* Main Code */
/* Do */
%IF ¶m2= %THEN %DO;
DATA random (DROP=i);
DO i=1 TO &n;
y = RAND('&dist', ¶m1);
x+1;
OUTPUT;
END;
RUN;
%END;
%ELSE %DO;
DATA random (DROP=i);
DO i=1 TO &n;
y = RAND('&dist', ¶m1, ¶m2);
x+1;
OUTPUT;
END;
RUN;
%END;
/* Stat */
%IF %UPCASE(&stats) = YES %THEN %DO;
PROC MEAN DATA = random MEAN STD;
VAR y;
RUN;
%END;
/* Plot */
%IF %UPCASE(&plot) = YES %THEN %DO;
PROC SGPLOT DATA = random;
HISTOGRAM y / BINWIDTH = 1;
DENSITY y / TYPE = kernel;
RUN;
%END;
/* Test Macro mymac */
%mymac(param1 = 0.2, stats = yes)
%mymac(dist=Geometric, param1=0.2, param2=, stats=yes)
%mymac(dist=Normal, param1=100, param2=10, n=1000, plot=yes)
Demo 2: Iterative - stack data sets
%MACRO myappend(start, stop);
%DO year = &start %TO &stop;
PROC import datafile = '&path\sales_&year..csv' OUT=sp4r_&year DBMS = csv REPLACE;
RUN;
PROC APPEND BASE = sp4r.sales_all DATA=sp4r.sales_&year;
RUN;
/* automatically initialize a null data set to be appended on */
PROC DATASETS LIBRARY = sp4r NOPRINT;
DETELE sales_&year;
QUIT;
%END;
%MEND;
OPTIONS MYPRINT;
/* print all the generated SAS code to log*/
%LET &mypath = s:workshop/;
%LET &mydata = sales_data;
%PUT &mypath.mydata..csv
%myappend(2000,2009)
Reference
- Github: SAS Programming for R Users
- Array
- Do Which? Loop, Until or While? A Review Of Data Step And Macro Algorithms
- PDV与数据读入