%macro burt(data=_last_, vars=, options=nomiss, out=Burt, );; %let _t = %sysfunc(time()); %if &data eq _last_ %then %let data = &syslast; proc contents data=&data(keep=&vars) noprint out=_cont(keep=length); run; data _null_; set _cont end=eof; retain max 0; max = max(length, max); if eof then do; l = floor(log10(_n_)) + 1; call symputx('_opt', catx(' ', getoption('source'), 'varlenchk=', getoption('varlenchk'))); call symputx('_f', l ); call symputx('_lablen', l + max + 1, 'G'); call symputx('_nvars', _n_, 'G'); call symputx('_nomiss', lowcase(symget('options')) eq 'nomiss'); end; run; options nosource varlenchk=nowarn; data _r2(keep=_r1 _r2) / view=_r2; length _r1 _r2 $ &_lablen; set &data(keep=&vars); array _x[&_nvars] $ &vars; %if &_nomiss %then %do; if cmiss(of _x[*]) eq 0; %end; do _j = 1 to &_nvars; _r1 = cats('v', put(_j,z&_f..), _x[_j]); _r2 = _r1; output; do _k = _j+1 to &_nvars; _r2 = cats('v', put(_k,z&_f..), _x[_k]); output; end; end; run; proc freq data=_r2; tables _r1 *_r2 / noprint sparse out=_c2(drop=p:); run; proc transpose data=_c2 out=_t1(drop=_n: _l:); by _r1; var count; id _r2; idlabel _r2; run; proc transpose data=_t1 out=_t2(drop=_n:); var _numeric_; id _r1; idlabel _r1; run; data _t2(drop=_j); length _label_ $ &_lablen; set _t2 end=_eof; array _x[*] _numeric_; do _j = _n_ + 1 to dim(_x); _x[_j] = .; end; if _n_ eq 1 then call execute('%nrstr(%%)macro _lab;'); call execute(catx(' ', 'label', vname(_x[_n_]), '=', quote(trim(substr(_label_, &_f+2))), ';')); if _eof then call execute('%nrstr(%%)mend;'); run; data &out(drop=_label_); label Label=' '; update _t1(rename=(_r1=_label_)) _t2; by _label_; Label = substr(_label_, &_f+2); %_lab run; proc datasets nolist; delete _cont _r2(memtype=view) _t1 _t2 _c2; quit; options &_opt; %let _t = %sysfunc(round(%sysevalf((%sysfunc(time()) - &_t)/60), 0.1)); %put Burt macro time=&_t minutes.; %mend;