The following example
uses the SUMDUP method to retrieve the summary value for the current
data item. It also illustrates that it is possible to loop backward
through the list by using the HAS_PREV and FIND_PREV methods. The
FIND_PREV method works similarly to the FIND_NEXT method with respect
to the current list item except that it moves backward through the
multiple item list.
data dup;
length key data 8;
input key data;
cards;
1 10
2 11
1 15
3 20
2 16
2 9
3 100
5 5
1 5
4 6
5 99
;
data _null_;
length r i sum 8;
i = 0;
dcl hash h(dataset:'dup', multidata: 'y', suminc: 'i');
h.definekey('key');
h.definedata('key', 'data');
h.definedone();
call missing (key, data);
i = 1;
do key = 1 to 5;
rc = h.find();
if (rc = 0) then do;
h.has_next(result: r);
do while(r ne 0);
rc = h.find_next();
rc = h.find_prev();
rc = h.find_next();
h.has_next(result: r);
end;
end;
end;
i = 0;
do key = 1 to 5;
rc = h.find();
if (rc = 0) then do;
h.sum(sum: sum);
put key= data= sum=;
h.has_next(result: r);
do while(r ne 0);
rc = h.find_next();
h.sumdup(sum: sum);
put 'dup ' key= data= sum=;
h.has_next(result: r);
end;
end;
end;
run;
The following lines
are written to the SAS log.
key=1 data=10 sum=2
dup key=1 data=15 sum=3
dup key=1 data=5 sum=2
key=2 data=11 sum=2
dup key=2 data=16 sum=3
dup key=2 data=9 sum=2
key=3 data=20 sum=2
dup key=3 data=100 sum=2
key=4 data=6 sum=1
key=5 data=5 sum=2
dup key=5 data=99 sum=2
To see how this works,
consider the key 1,which has three data values: 10, 15, and 5 (which
are stored in that order).
key=1 data=10 sum=2
dup key=1 data=15 sum=3
dup key=1 data=5 sum=2
When traveling through
the data list in the loop, the key summary for 10 is set to 1 on the
initial FIND method call. The first FIND_NEXT method call sets the
key summary for 5 to 1. The next FIND_PREV method call moves back
to the data value 10 and increments its key summary to 2. Finally,
the last call to the FIND_NEXT method increments the key summary for
5 to 2. The next iteration through the loop sets the key summary for
15 to 1 and the key summary for 5 to 3 (because 5 is stored before
15 in the list). Finally, the key summary for 15 is incremented to
2. This processing results in the output for key 1 as shown in Output
5.10.
Note that you do not
call the HAS_PREV method before calling the FIND_PREV method in this
example because you already know that there is a previous entry in
the list. Otherwise, you would not have gotten into the loop.
This example illustrates
that there is no guaranteed order for multiple data items for a given
key because they all have the same key. SAS cannot sort on the key.
The order in the list (10, 5, 15) does not match the order that the
items were added.
Also shown here is the
necessity of having special methods for some duplicate operations
(in this case, the SUMDUP method works similarly to the SUM method
by retrieving the key summary for the current list item).