SAS: Loop

- 4 mins

Overview

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:

%MACRO <macro-name>;
	SAS-statements;
%MEND
%MACRO <macro-name>(<parameter-1>, <parameter-2>);
	SAS-statements;
%MEND

%<macro-name>(x, y)
%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 &param1= %THEN %DO;
	%PUT param1 is a required argument;
	%RETURN;
%END;

/* Main Code */
/* Do */
%IF &param2= %THEN %DO;
	DATA random (DROP=i);
		DO i=1 TO &n;
			y = RAND('&dist', &param1);
			x+1;
			OUTPUT;
		END;
	RUN;
%END;

%ELSE %DO;
	DATA random (DROP=i);
		DO i=1 TO &n;
			y = RAND('&dist', &param1, &param2);
			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

Zhijian Liu

Zhijian Liu

A foodaholic

comments powered by Disqus
rss facebook twitter github gitlab youtube mail spotify lastfm instagram linkedin google google-plus pinterest medium vimeo stackoverflow reddit quora quora