Once upon a midnight dreary,
While I pondered, weak and weary,
Over many a quaint and curious
Volume of SAS-L galore,
While I coded, nearly snapping,
Suddenly there came a tapping
As of someone gently wrapping
Code around my mental core.
“’Tis’ Do-Whitlock Loop”, I muttered,
“Wrapped around my brain core” –
This it was, and so much more!
–Paul Dorfman, A Bit of DoW-History
It’s great to have Paul Dorfman’s demo of DoW-loop (with a poem! Thanks to Paul to send me a copy.) in this SESUG 2012 conference. First posted in SAS-L by Whitlock, promoted by Dorfman, DoW-loop is wildly known as “Whitlock Do Loop” or ” Dorfman-Whitlock Do Loop”. In Dorfman’s presentation, the following three forms of DoW-loop were constructed:
-
Henderson-Whitlock Original Form of DoW-loop
-
Dorfman’s Short Form of DoW-loop
-
Double DoW-loop: the DeVenezia-Schreier Form
Using a test data set
data a;
input id $ var;
datalines;
A 1
A 2
B 3
B 4
B 5
;
the Henderson-Whitlock Original Form of DoW-loop looks like:
data b;
count= 0;
sum = 0 ;do until ( last.id ) ;
set a ;
by id ;count+1;
sum+var;
end ;mean = sum / count ;
run ;
Ian Whitlock first used such kind of do loop in a SAS-L post and after its rising, Paul Dorfman, the main promoter of DoW-loop, found that Don Henderson also made use such DO UNTIL() structure in a NESUG 1988 paper, The SAS Supervisor. That’s why he named it as Henderson-Whitlock form of DoW-loop. I then read from a DoW-loop page in sascommunity.org that Don Henderson taught such concept in class where Ian Whitlock was a student. This is a nice story.
Paul Dorfman himself also contributed a short form:
data c ;
do n = 1 by 1 until ( last.id ) ;
set a ;
by id ;count = sum (count, 1) ;
sum = sum (sum, var) ;
end ;mean = sum / count ;
run ;
This kind of form of DoW-loop utilizes the SUM function and an increment trick in DO UNTIL() structure then the initializations before the loop are not needed any more.
The double DoW-loop is under the name Howard Schreier and Richard DeVenezia (DeVenezia-Schreier Form; I should do more literature research on it!):
data d ;
do n = 1 by 1 until ( last.id ) ;
set a ;
by id ;count = sum (count, 1) ;
sum = sum (sum, var) ;
end ;mean = sum / count ;
do n = 1 by 1 until ( last.id ) ;
set a ;
by id ;
output;
end ;
run ;