Title: Eliminate%20Cookie-Cutter%20Code%20with%20%wordLoop
1Eliminate Cookie-Cutter Code with wordLoop
David.Abbott_at_va.gov
2Def. of CCC How It Is Created
- Write a short chunk of SAS code
- Copy, paste, edit
- Copy, paste, edit
- Copy, paste, edit
- (until the list in mind is exhausted)
3Why diss Cookie-Cutter Code?
Now vs. later
Excellence
Competence
vs.
4wordLoop Signature
wordLoop( wordListltgt, contentMacroltgt) Where
wordList gt values to loop over, e.g. data set
names contentMacro gt code applied on each loop
5Example Code
- Select a subset of observations from each of N
datasets - Create N new suitably-named datasets
- Subset specified by finderFileDs
- Why? subset analysis, data transfer, removal of
patients from study
6Example Cookie-Cutter Code
DATA patientDs_subset MERGE patientDs(inin1)
finderFileDs(inin2)BY id IF in1 and
in2 RUN DATA consultDs_subset MERGE
consultDs(inin1) finderFileDs(inin2)BY id
IF in1 and in2 RUN DATA hospStayDs_subset
MERGE hospStayDs(inin1) finderFileDs(inin2)BY
id IF in1 and in2 RUN DATA eventsDs_subset
MERGE eventsDs(inin1) finderFileDs(inin2)BY
id IF in1 and in2 RUN DATA drugsDs_subset
MERGE drugsDs(inin1) finderFileDs(inin2)BY
id IF in1 and in2 RUN
7Ex. CCC showing Substitutions
DATA patientDs_subset MERGE patientDs(inin1)
finderFileDs(inin2)BY id IF in1 and
in2 RUN DATA consultDs_subset MERGE
consultDs(inin1) finderFileDs(inin2)BY id
IF in1 and in2 RUN DATA hospStayDs_subset
MERGE hospStayDs(inin1) finderFileDs(inin2)BY
id IF in1 and in2 RUN DATA eventsDs_subset
MERGE eventsDs(inin1) finderFileDs(inin2)BY
id IF in1 and in2 RUN DATA drugsDs_subset
MERGE drugsDs(inin1) finderFileDs(inin2)BY
id IF in1 and in2 RUN
8 Repeating Pattern
DATA ltDs from listgt_subset MERGE ltDs from
listgt(inin1) finderFileDs(inin2) BY id IF
in1 and in2 RUN
Ds list patientDs consultDs hospStayDs
eventDs drugDs
9Liabilities of CCC
- Cut-paste-edit errors
- Bulky and hard to read
- Tedious to change implementation
- List is hidden
- List tedious to change
Make a macro of repeating element?
10 Ex. with Macro Definition
MACRO getSubset(ofDs) DATA ofDs._subset
MERGE ofDs(inin1) finderFileDs (inin2)
BY id IF in1 and in2 RUN MEND getSubse
t(ofDspatientDs ) getSubset(ofDsconsultDs
) getSubset(ofDshospStayDs) getSubset(ofDsev
entsDs ) getSubset(ofDsdrugsDs )
Still got cookies!
Still list elements are dispersed.
11Ex. with wordLoop
MACRO getSubset( ) DATA word._subset
MERGE word.(inin1) finderFileDs(inin2) BY
id IF in1 and in2 RUN MEND LET
dspatientDs consultDs hospStayDs eventsDs
drugsDs wordLoop(wordListds,contentMacrogetSu
bset( ))
Oops! What about sort order?
12Again with sort
MACRO getSubset() proc sort DATAword BY
id RUN DATA word._subset MERGE
word.(inin1) finderFileDs(inin2) BY id
IF in1 and in2 RUN MEND LET
dspatientDs consultDs hospStayDs eventsDs
drugsDs wordLoop(wordListds,contentMacrogetSu
bset( ))
SQL better?
13Again with SQL
MACRO getSubset() PROC sql create table
word._subset as select from word,
finderFileDs where word..id
finderFileDs.id QUIT MEND LET
dspatientDs consultDs hospStayDs eventsDs
drugsDs wordLoop(wordListds,contentMacrogetSu
bset( ))
Change localized!
14wordLoop code
MACRO wordLoop(wordList, contentMacro)
LOCAL word cnt LET cnt0 DO WHILE(1 eq
1) LET cnt eval(cnt1) LET
word scan(wordList, cnt, str( )) IF
word THEN RETURN contentMacro
END MEND wordLoop
ContentMacro must not LOCAL word!
15Example 2 Code
- Recode 99 to . for selected variables
- 5 variables need to be recoded
- 3 variables might have valid 99s
- CCC occurs within a DATA step
16Ex. 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
17Ex. 2 with Array Solution
LET varsWith99 eyeColor hairColor bloodtype
prevCardiac prevCancer DATA data99sFixedDs
SET dataWith99sDs ARRAY vars99arr
varsWith99 DO i1 to dim(vars99arr) IF
vars99arr(i) eq 99 THEN vars99arr(i) . END
DROP i RUN
This works but so does
18Ex. 2 with wordLoop
LET varsWith99 eyeColor hairColor bloodtype
prevCardiac prevCancer MACRO cnvt99s() IF
word eq 99 THEN word . MEND DATA
data99sFixed SETdataWith99sDs
wordLoop(wordListvarsWith99,
contentMacrocnvt99s()) RUN
19Misuses of wordLoop
- Avoid use with datasets representing partitions
of DATA (e.g. sites) - Combine and processBY site, instead
- Avoid use with procs whenBY or CLASS can be used
(e.g. PROC MEANS)
20Take Aways
- Avoid cookie-cutter-code!
- wordLoop() can help you do this
- SAS macros allow you to adapt the SAS language to
your purposes.
David.Abbott_at_va.gov
21Big Picture
- Illustrate and define cookie-cutter code
- Discuss the liabilities of same
- Present the user view of wordLoop
- Use it to eliminate the cookie-cutter code
- wordLoop implementation