As featured in: Data Management Solutions Using SAS Hash Table Operations: A Business Intelligence Case Study , and built from this github repository.
Chapter 8 MeanMedianMode.sas
1 /* "Chapter 8 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 %let Var = Distance;
7 
8 data ptiles;
9  input Ptile;
10  Metric = put(Ptile,percent6.);
11  retain Value . ;
12  datalines;
13  .05
14  .1
15  .25
16  .5
17  .75
18  .95
19 ;
20 
21 data _null_;
22 
23  format Percent Cum_Percent percent7.2;
24 
25  dcl hash metrics(dataset:"ptiles"
26  ,multidata:"Y"
27  ,ordered:"A");
28  metrics.defineKey("Ptile");
29  metrics.defineData("Ptile","Metric","Value");
30  metrics.defineDone();
31  dcl hiter iterPtiles("metrics");
32 
33  dcl hash distribution(ordered:"A");
34  distribution.defineKey("&Var");
35  distribution.defineData("&Var","Count","Percent","Cumulative","Cum_Percent");
36  distribution.defineDone();
37  dcl hiter iterDist("distribution");
38  do Rows = 1 by 1 until(lr);
39  set dw.AtBats(keep=&Var) end=lr;
40  where &Var gt .;
41  if distribution.find() ne 0 then Count = 0;
42  Count + 1;
43  distribution.replace();
44  Total + &Var;
45  maxCount = max(Count,maxCount);
46  end;
47 
48  iterPtiles.first();
49  last = .;
50  do i = 1 to distribution.num_items;
51  iterDist.next();
52  Percent = divide(Count,Rows);
53  _Cum + Count;
54  Cumulative = _Cum;
55  Cum_Percent = divide(_Cum,Rows);
56  distribution.replace();
57  if Count = maxCount then metrics.add(Key:.,Data:. ,Data:"Mode",Data:&Var);
58  if last le ptile le Cum_Percent then
59  do; /* found the percentile */
60  Value = &Var;
61  if ptile ne 1 then metrics.replace();
62  if iterPtiles.next() ne 0 then ptile = 1;
63  end; /* found the percentile */
64  last = Cum_Percent;
65  end;
66 
67  metrics.add(Key:.,Data:.,Data:"Mean",Data:divide(Total,Rows));
68 
69  iterDist.first();
70  metrics.add(Key:.,Data:.,Data:"Min",Data:&Var);
71 
72  iterDist.last();
73  metrics.add(Key:.,Data:.,Data:"Max",Data:&Var);
74 
75  metrics.output(dataset:"Metrics(drop=ptile)");
76  distribution.output(dataset:"Distribution");
77 
78  stop;
79  set ptiles;
80 run;