/* Here are several examples of different DO loop styles. The data set contains travel expenditures. Variables are: name, expense code, and amount. Each person may have a variable number of expenses. The first examples use DO UNTIL. The UNTIL expression is evaluated at the bottom of the loop. */ options ls=100; filename foo url "http://www.uvm.edu/~abh/stat295/datasets/travel.dat"; data expense; infile foo; length name $ 8 code $ 1 ; input name @; do until (code = " "); input code amount @ ; output; end; run; proc print; title "DO UNTIL example"; run; /* The above does not work because list input will automatically go to the next line of data to try to find some. A new value for name is never read. */ data expense; infile foo missover; length name $ 8 code $ 1 ; input name @; do until (code = " "); input code amount @ ; output; end; run; proc print; title "DO UNTIL example"; run; /* The above reads correctly because of the missover option but a missing observation for each name is output. */ data expense; infile foo missover; length name $ 8 code $ 1 ; input name @; do until (code = " "); input code amount @ ; if code ne " " then output; end; run; proc print; title "DO UNTIL example"; run; /* The above reads and outputs correctly, but has two tests for the value of code. One of them can be eliminated by putting the output statement ahead of the input. */ data expense; infile foo missover; length name $ 8 code $ 1 ; input name code amount @; do until (code = " "); output; input code amount @ ; end; run; proc print; title "DO UNTIL example"; run; /* Now we have relatively efficient code, but if a name has no codes associated with it, a missing observation will be output, because we eliminated the second test. */ filename foo2 url "http://www.uvm.edu/~abh/stat295/datasets/travel2.dat"; data expense; infile foo2 missover; length name $ 8 code $ 1 ; input name code amount @; do until (code = " "); output; input code amount @ ; end; run; proc print; title "DO UNTIL example"; run; /* To keep the code efficient and eliminate this problem, use DO WHILE instead of DO UNTIL. DO WHILE evaluates the expression at the top of the loop so, if the expression is false, the loop does not get executed. */ data expense; infile foo2 missover; length name $ 8 code $ 1 ; input name code amount @; do while (code ne " "); output; input code amount @ ; end; run; proc print; title "DO WHILE example"; run; /* Here is an example of using a DO loop to generate normally distributed random data. */ data norm; do _i_ = 1 to 100000; x = rannor(0); end; run; proc means; var x; title "Random data generated in DO loop"; run; /* What's wrong with the above DO loop and how do we fix it? */ data norm; do _i_ = 1 to 100000; x = rannor(0); output; end; run; proc means; var x; title "Random data generated in DO loop"; run;