From: "Data _null_;" on
Yesterday "Proc Me" and I were discussing using associative arrays for
counting, similar to PROC FREQ.

I thought this HOH to produce One Way Freqs was mildly interesting.

It demonstrates using VNEXT to aquire variable names at data step
runtime then uses that information to declare the hashes to accumulate
the counts. The variables of interest are listed in a dummy BY
statement for ease of retrievial from the PDV.

It also demonstrates using "nested iterators" to output the one way
tables in a format similar to the ODS table OneWayFreqs.

%let data = sashelp.shoes;
%let Tables = product region;

data OneWayFreqs(drop=__:);
length _name_ $40 _freq_ _cfreq_ 8;
if 0 then do;
set &data(keep=&tables);
by &tables;
end;

/* hash and iterator for freq HASHES*/
declare hash v;
v = _new_ hash();
declare hiter i;
i = _new_ hiter('v');
v.defineKey('_name_');
v.defineData('_name_','h','hi');
v.defineDone();

/* hash and iterator for each var in &tables */
declare hash h;
declare hiter hi;
do _N_ = 1 by 1;
call vnext(_name_);
if missing(_NAME_) then leave;
if _name_ ne: 'FIRST.' then continue;
_name_ = scan(_name_,2,'.');
h = _new_ hash(ordered:'a');
hi = _new_ hiter('h');
h.defineKey(_name_);
h.defineData(_name_);
h.defineData('_freq_');
h.defineDone();
v.add();
put 'NOTE: One Way Freqs for variable=' _name_;
end;

/* accumlate the frequency for each var */
do until(eof);
set &data(keep=&tables) end=eof;
do __rc=i.first() by 0 while(__rc eq 0);
call missing(_freq_);
__rch = h.find();
_freq_ + 1;
__rch = h.replace();
__rc = i.next();
end;
end;

call missing(of _all_);

/* create an output data set similar to ODS table ONEWAYFREQS */
do __rc=i.first() by 0 while(__rc eq 0);
do __rchi=hi.first() by 0 while(__rchi eq 0);
_cfreq_ + _freq_;
output;
__rchi = hi.next();
end;
call missing(of _all_);
__rc = i.next();
end;
stop;
run;
proc contents data=onewayfreqs;
run;
proc print data=onewayfreqs;
run;