Top Banner
1 Eliminate Cookie- Eliminate Cookie- Cutter Code Cutter Code with with %wordLoop %wordLoop 1 [email protected]
20

1 Eliminate Cookie-Cutter Code with %wordLoop 1 [email protected].

Dec 14, 2015

Download

Documents

Kenia Broadbent
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: 1 Eliminate Cookie-Cutter Code with %wordLoop 1 David.Abbott@va.gov.

1

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

11

[email protected]

Page 2: 1 Eliminate Cookie-Cutter Code with %wordLoop 1 David.Abbott@va.gov.

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)

Page 3: 1 Eliminate Cookie-Cutter Code with %wordLoop 1 David.Abbott@va.gov.

3

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

33

Now vs. later

vs.

Page 4: 1 Eliminate Cookie-Cutter Code with %wordLoop 1 David.Abbott@va.gov.

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

Page 5: 1 Eliminate Cookie-Cutter Code with %wordLoop 1 David.Abbott@va.gov.

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

Page 6: 1 Eliminate Cookie-Cutter Code with %wordLoop 1 David.Abbott@va.gov.

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;

Page 7: 1 Eliminate Cookie-Cutter Code with %wordLoop 1 David.Abbott@va.gov.

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;

Page 8: 1 Eliminate Cookie-Cutter Code with %wordLoop 1 David.Abbott@va.gov.

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

Page 9: 1 Eliminate Cookie-Cutter Code with %wordLoop 1 David.Abbott@va.gov.

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?

Page 10: 1 Eliminate Cookie-Cutter Code with %wordLoop 1 David.Abbott@va.gov.

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.

Page 11: 1 Eliminate Cookie-Cutter Code with %wordLoop 1 David.Abbott@va.gov.

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?

Page 12: 1 Eliminate Cookie-Cutter Code with %wordLoop 1 David.Abbott@va.gov.

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?

Page 13: 1 Eliminate Cookie-Cutter Code with %wordLoop 1 David.Abbott@va.gov.

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!

Page 14: 1 Eliminate Cookie-Cutter Code with %wordLoop 1 David.Abbott@va.gov.

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!

Page 15: 1 Eliminate Cookie-Cutter Code with %wordLoop 1 David.Abbott@va.gov.

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

Page 16: 1 Eliminate Cookie-Cutter Code with %wordLoop 1 David.Abbott@va.gov.

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;

Page 17: 1 Eliminate Cookie-Cutter Code with %wordLoop 1 David.Abbott@va.gov.

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 …

Page 18: 1 Eliminate Cookie-Cutter Code with %wordLoop 1 David.Abbott@va.gov.

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;

Page 19: 1 Eliminate Cookie-Cutter Code with %wordLoop 1 David.Abbott@va.gov.

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)

Page 20: 1 Eliminate Cookie-Cutter Code with %wordLoop 1 David.Abbott@va.gov.

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]