As featured in: Data Management Solutions Using SAS Hash Table Operations: A Business Intelligence Case Study , and built from this github repository.
Chapter 9 HoH MeanMedianMode.sas
1 /* "Chapter 9 HoH MeanMedianMode.sas" from the SAS Press book
2  Data Management Solutions Using SAS Hash Table Operations:
3  A Business Intelligence Case Study
4 */
5 
6 data Ptiles;
7  input Percentile;
8  Metric = put(Percentile,percent8.);
9  datalines;
10 .05
11 .1
12 .25
13 .5
14 .75
15 .95
16 ;
17 
18 data Variables;
19  infile datalines;
20  length Variable $32;
21  input Variable $32.;
22  datalines;
23 Distance
24 Direction
25 ;
26 
27 proc sql noprint;
28  select distinct Variable
29  into:Vars separated by ' '
30  from Variables;
31 quit;
32 
33 data Distributions(keep=Variable Value Count Percent Cumulative Cum_Percent);
34  length Variable $32 Value 8 Metric $8;
35  format Count Cumulative total comma12. Percent Cum_Percent percent7.2;
36  array _Variables(*) &Vars;
37 
38  dcl hash ptiles(dataset:"ptiles",ordered:"A");
39  ptiles.defineKey("Percentile");
40  ptiles.defineData("Percentile","Metric");
41  ptiles.defineDone();
42  dcl hiter iter_ptiles("ptiles");
43 
44  dcl hash results(ordered:"A",multidata:"Y");
45  results.defineKey("Variable","Metric");
46  results.defineData("Variable","Metric","Value");
47  results.defineDone();
48 
49  dcl hash HoH(ordered:"A");
50  HoH.defineKey ("I");
51  HoH.defineData ("H","ITER","Variable","Total","Sum","maxCount");
52  HoH.defineDone();
53  dcl hash h();
54  dcl hiter iter;
55 
56  do I = 1 to dim(_Variables);
57  h = _new_ hash(ordered:"A");
58  h.defineKey(vname(_Variables(i)));
59  h.defineData(vname(_Variables(i)),"Count");
60  h.defineDone();
61  iter = _new_ hiter("H");
62  Variable = vname(_Variables(i));
63  HoH.add();
64  end;
65 
66  maxCount=0;
67  do Rows = 1 by 1 until(lr);
68  set dw.AtBats end=lr;
69  do I = 1 to dim(_Variables);
70  HoH.find();
71  if missing(_Variables(i)) then continue;
72  if h.find() ne 0 then Count = 0;
73  Count + 1;
74  h.replace();
75  Total + 1;
76  Sum + _Variables(I);
77  maxCount = max(Count,maxCount);
78  HoH.replace();
79  end;
80  end;
81  do I = 1 to dim(_Variables);
82  _cum = 0;
83  HoH.find();
84  iter_ptiles.first();
85  last = .;
86  do j = 1 to h.num_items;
87  iter.next();
88  Percent = divide(Count,Total);
89  _Cum + Count;
90  Cumulative = _Cum;
91  Cum_Percent = divide(_Cum,Total);
92  Value = _Variables(I); /*vvalue(_Variables(I))*/
93  output;
94  if Count = maxCount
95  then results.add(Key:Variable
96  ,Key:"Mode"
97  ,Data:Variable
98  ,Data:"Mode"
99  ,Data:_Variables(I) /*vvalue(_Variables(I))*/
100  );
101  if last le Percentile le Cum_Percent then
102  do; /* found the percentile */
103  if percentile ne 1 then results.add();
104  if iter_ptiles.next() ne 0 then percentile = 1;
105  end; /* found the percentile */
106  last = Cum_Percent;
107  end;
108  Value = divide(Sum,Total);
109  Metric = "Mean";
110  results.add();
111  iter.first();
112  Value = _Variables(I); /*vvalue(_Variables(I))*/
113  Metric = "Min";
114  results.add();
115  iter.last();
116  Value = _Variables(I); /*vvalue(_Variables(I))*/
117  Metric = "Max";
118  results.add();
119  end;
120  results.output(dataset:"Metrics");
121  stop;
122  set ptiles;
123 run;