In the blog post A Hash Object of Hash Objects, I introduce the hash of hash (HoH) technique by example. In the post, we learn that a hash object can contain other hash objects. A more correct way of saying this is that a hash object can contain non-scalar type variables in the data portion. When a hash object is declared (not instantiated), SAS creates a non-scalar variable of type ‘hash’ in the PDV. When a hash object contains a hash-type variable, it acts as a pointer to the active instance of the hash object with the same as the variable.

The hash of hashes technique is advanced. Also, not a lot of material exists on the topic. However, a few brilliant SAS minds out there have used it flawlessly from time to time. This post will serve as a summary of the best examples of using the HoH technique, that I have seen.

Building Provider Panels in SAS

First, see the article Building Provider Panels: An Application for the Hash of Hashes by Richard A. Devenezia. The first thing that caught my eye in this article is a quite fitting description of the hash of hashes: “A multi-dimensional array on steroids”.

In the article, we see how to process claims data to determine which provider within a given specialty is most likely overseeing a patient’s care in healthcare data. Three different approaches are presented: Proc SQl, the DoW Loop and the hash of hashes. The article is a very nice presentation of a real-life application of the hoh technique.

Hash of Hashes – The Russian Doll

The article The Hash-of-Hashes as a “Russian Doll” Structure by Joseph Hinson shows how to use the HoH technique to create a nested XML model from a SAS data set. A quite interesting application and the structure is very well explained in the article. Even if you are not interested in the XML structure itself, you will gain knowledge on the hierarchal structure of the hash of hashes.

An Alternative to the NLevels PROC FREQ

Paul Dorfman and Don Henderson wrote a very nice article at SAS Global Forum 2020: Dynamic Programming With The SAS Hash Object. The article contains a few pages on the HoH method. Specifically, there is a nice example of how to present the number of variable levels for a number of variables in a SAS Data Set. Novice SAS programmers will recognize this as exactly the task of the NLevels Option in PROC FREQ. Therefore, consider the code below (from the article). First, PROC FREQ is used with the NLevels options. This creates a data set with an observations for each variable N1-N5 and a variable, that gives us the number of levels in each variable.

 data have;
 input N1-N5;
 cards;
3 5 4 7 9
1 6 4 2 5
1 5 4 7 7
8 6 4 9 3
1 5 4 1 8
; 
 
proc freq data=have nlevels;
    ods output nlevels=want_nlevels;
run;

Next, consider the code below. This is a HoH approach to do the same thing as above. However it uses much less memory. For a detailed explanation of the code, read the article. It is well worth the time.

data want_hoh (keep = nvar count);
    set have end = end;
    array nn N1-N5;
    if _n_ = 1 then do;
        dcl hash hh ();
        hh.definekey ("_i_");
        hh.definedata ("h");
        hh.definedone ();
        do over nn;
            dcl hash h ();
            h.definekey ("_n_");
            h.definedone ();
            hh.add();
        end;
    end;
    do over nn;
        hh.find();
        h.ref (key:nn, data:nn);
    end;
    if end then do over nn;
        Nvar = put (vname (nn), $8.);
        hh.find();
        Count = h.num_items;
        output;
    end;
run;

Advanced Stacks and Queues

In a previous blog post, I write about How To Create FIFO Queues in SAS with the Hash Object. In the article From Stocks to Flows: Using SAS Hash Objects for FIFO, LIFO, and other FO’s, Mark Keintz takes it a few steps further. Here, the HoH technique to create more advanced stacks and queues. For example, HIFO (highest price first out) and LOFO (lowest price) stacks are created. This article demonstrates how flexible the HoH technique is. I highly recommend reading it.

Single Key Changes in Multi Key Hash Objects

Last week, I blogged about how to detect Single Key Changes in Multi Key Hash Objects. Not a trivial assignment. I present a few techniques that I learned at SAS-L. The most flexible and intuitive solution though, is the HoH approach. You can see the code below. For a detailed explanation, read the blog post.

data _null_;
 
   dcl hash hoh ();
   hoh.definekey("k1");
   hoh.definedata("h", "hi", "k1");
   hoh.definedone();
   dcl hiter i ("hoh");
 
   dcl hash h;
 
   do until (lr);
      set have end=lr;
      if hoh.find() ne 0 then do;
         h = _new_ hash (multidata : "Y");
         h.definekey ("k1", "k2");
         h.definedata ("k1", "k2", "d");
         h.definedone();
         declare hiter hi ("h");
         hoh.add();
      end;
      h.add();
   end;
 
   do while (i.next() = 0);
      put "** New key **";
      do while (hi.next()=0);
         put (k1 k2 d)(=);
      end;
   end;
run;

Summary

In this post, I demonstrate a few real-life applications of the Hash of Hashes technique in SAS. If I missed a good example, let me know. As a reference, the book Data Management Solutions Using SAS Hash Table Operations has an entire chapter on the topic.

You can download the entire code from this post here.