Transcript

1

Eliminate Cookie-Cutter Eliminate Cookie-Cutter CodeCode withwith %wordLoop %wordLoop

11

[email protected]

2

Def. of CCC – How It Is Def. of CCC – How It Is CreatedCreated

Write a short chunk of SAS codeWrite a short chunk of SAS code Copy, paste, editCopy, paste, edit Copy, paste, editCopy, paste, edit Copy, paste, editCopy, paste, edit … … (until the list in (until the list in mindmind is is

exhausted)exhausted)

3

Why diss Cookie-Cutter Why diss Cookie-Cutter Code?Code?

33

Now vs. later

vs.

4

%wordLoop Signature%wordLoop Signature

%wordLoop( wordList=<>, contentMacro=<>);

Where: wordList => values to loop over, e.g. data set names contentMacro => code applied on each loop

5

Example Code Example Code

Select a subset of observations from Select a subset of observations from each of N datasets each of N datasets

Create N new suitably-named Create N new suitably-named datasetsdatasets

Subset specified by Subset specified by finderFileDsfinderFileDs Why? subset analysis, data transfer, Why? subset analysis, data transfer,

removal of patients from studyremoval of patients from study

6

Example Cookie-Cutter Example Cookie-Cutter CodeCode

DATA patientDs_subset; MERGE patientDs(in=in1) finderFileDs(in=in2);BY id; IF in1 and in2;RUN;DATA consultDs_subset; MERGE consultDs(in=in1) finderFileDs(in=in2);BY id; IF in1 and in2;RUN;DATA hospStayDs_subset; MERGE hospStayDs(in=in1) finderFileDs(in=in2);BY id; IF in1 and in2;RUN;DATA eventsDs_subset; MERGE eventsDs(in=in1) finderFileDs(in=in2);BY id; IF in1 and in2;RUN;DATA drugsDs_subset; MERGE drugsDs(in=in1) finderFileDs(in=in2);BY id; IF in1 and in2;RUN;

7

Ex. CCC showing Ex. CCC showing SubstitutionsSubstitutions

DATA patientDs_subset; MERGE patientDs(in=in1) finderFileDs(in=in2);BY id; IF in1 and in2;RUN;DATA consultDs_subset; MERGE consultDs(in=in1) finderFileDs(in=in2);BY id; IF in1 and in2;RUN;DATA hospStayDs_subset; MERGE hospStayDs(in=in1) finderFileDs(in=in2);BY id; IF in1 and in2;RUN;DATA eventsDs_subset; MERGE eventsDs(in=in1) finderFileDs(in=in2);BY id; IF in1 and in2;RUN;DATA drugsDs_subset; MERGE drugsDs(in=in1) finderFileDs(in=in2);BY id; IF in1 and in2;RUN;

8

Repeating PatternRepeating Pattern

DATA <Ds from list>_subset; MERGE <Ds from list>(in=in1) finderFileDs(in=in2); BY id; IF in1 and in2;RUN;

Ds list: patientDs consultDs hospStayDs eventDs drugDs

9

Liabilities of CCCLiabilities of CCC

Cut-paste-edit errorsCut-paste-edit errors Bulky and hard to readBulky and hard to read Tedious to change implementationTedious to change implementation List is hiddenList is hidden List tedious to changeList tedious to change

Make a macro of repeating element?

10

Ex. with Macro DefinitionEx. with Macro Definition

%MACRO getSubset(ofDs=); DATA &ofDs._subset; MERGE &ofDs(in=in1) finderFileDs (in=in2); BY id; IF in1 and in2; RUN;%MEND;%getSubset(ofDs=patientDs );%getSubset(ofDs=consultDs );%getSubset(ofDs=hospStayDs);%getSubset(ofDs=eventsDs );%getSubset(ofDs=drugsDs );

Still got cookies!

Still list elements are dispersed.

11

Ex. with %wordLoop Ex. with %wordLoop

%MACRO getSubset( ); DATA &word._subset; MERGE &word.(in=in1) finderFileDs(in=in2); BY id; IF in1 and in2; RUN;%MEND;

%LET ds=patientDs consultDs hospStayDs eventsDs drugsDs;%wordLoop(wordList=&ds,contentMacro=getSubset( ));

Oops! What about sort order?

12

Again with sortAgain with sort

%MACRO getSubset(); proc sort DATA=&word; BY id; RUN; DATA &word._subset; MERGE &word.(in=in1) finderFileDs(in=in2); BY id; IF in1 and in2; RUN;%MEND;

%LET ds=patientDs consultDs hospStayDs eventsDs drugsDs;%wordLoop(wordList=&ds,contentMacro=getSubset( ));

SQL better?

13

Again with SQLAgain with SQL

%MACRO getSubset(); PROC sql; create table &word._subset as select * from &word, finderFileDs where &word..id = finderFileDs.id; QUIT; %MEND;

%LET ds=patientDs consultDs hospStayDs eventsDs drugsDs;%wordLoop(wordList=&ds,contentMacro=getSubset( ));

Change localized!

14

%wordLoop code %wordLoop code

%MACRO wordLoop(wordList=, contentMacro=); %LOCAL word cnt; %LET cnt=0; %DO %WHILE(1 eq 1); %LET cnt = %eval(&cnt+1); %LET word= %scan(&wordList, &cnt, %str( )); %IF &word= %THEN %RETURN; %&contentMacro; %END;%MEND wordLoop;

ContentMacro must not %LOCAL word!

15

Example 2 Code Example 2 Code

Recode 99 to “.” for selected Recode 99 to “.” for selected variablesvariables

5 variables need to be recoded5 variables need to be recoded 3 variables might have valid 99s3 variables might have valid 99s CCC occurs within a DATA step CCC occurs within a DATA step

16

Ex. 2 Cookie-Cutter CodeEx. 2 Cookie-Cutter Code

DATA data99sFixed; SETdataWith99sDs; IF eyeColor eq 99 THEN eyeColor = .; IF hairColor eq 99 THEN hairColor = .; IF bloodtype eq 99 THEN bloodtype = .; IF prevCardiac eq 99 THEN prevCardiac = .; IF prevCancer eq 99 THEN prevCancer = .;RUN;

17

Ex. 2 with Array SolutionEx. 2 with Array Solution

%LET varsWith99 = eyeColor hairColor bloodtype prevCardiac prevCancer;

DATA data99sFixedDs; SET dataWith99sDs; ARRAY vars99arr{*} &varsWith99; DO i=1 to dim(vars99arr); IF vars99arr(i) eq 99 THEN vars99arr(i) = .; END; DROP i;RUN;

This works but so does …

18

Ex. 2 with %wordLoop Ex. 2 with %wordLoop

%LET varsWith99 = eyeColor hairColor bloodtype prevCardiac prevCancer;

%MACRO cnvt99s(); IF &word eq 99 THEN &word= .;%MEND;

DATA data99sFixed; SETdataWith99sDs; %wordLoop(wordList=&varsWith99, contentMacro=cnvt99s());RUN;

19

Misuses of %wordLoopMisuses of %wordLoop

Avoid use with datasets representing Avoid use with datasets representing partitions of DATA (e.g. sites)partitions of DATA (e.g. sites)

Combine and processBY site, insteadCombine and processBY site, instead Avoid use with procs whenBY or Avoid use with procs whenBY or

CLASS can be used (e.g. PROC CLASS can be used (e.g. PROC MEANS) MEANS)

20

Take AwaysTake Aways Avoid cookie-cutter-code!Avoid cookie-cutter-code! %wordLoop() can help you do this%wordLoop() can help you do this SAS macros allow you to adapt the SAS macros allow you to adapt the

SAS language to your purposes.SAS language to your purposes.

[email protected]


Recommended