Processing Check-All-That-Apply
From sasCommunity
This article contains a new implementation of ShowComb. See paper cited in References.
Caveat: Untested code from the Clue?Gee! Wrx!
Note: This routine depends on the variable having a label which contains the descriptive text which is to be used in the Combination variable.
DATA MyData
attrib VarA length = $ 1 label = 'Apple'
VarB length = $ 1 label = 'Banana'
VarC length = $ 1 label = 'Cherries'
;
*insert test data with variables labeled here;
*name: ProcFreq2comb.sas;
/****************************************************
*a parameterized include program;
%Let Libname = sashelp;
%Let Libname = Work;
%Let Memname = Class;
%Let Memname = MyData;
%Let Names = Q01A Q01B Q01C;
%Let Names = VarA VarB VarC;
%Let Series = Q01;
%Let Series = Var;
%Let SeriesChar = :;*note: label = 'Q01: Description';
%Let SeriesChar = ;*none;
%Let True = '1';*char: 0/1;
%Let True = 'Y';*char: Y/N;
%*Let True = 1;*numeric: 0/1;
%Let TypeCn = $;*char;
%*Let TypeCn = ;*numeric;
%Let TypeLength = 1;*char1 for 'Y';
%*Let TypeLength = 8;*numeric;
%Let ByVar = ;
%Let Out_Libname = Library;
%Let Out_Libname = LibSmry;
%Let Out_Libname = Work;
/****************************************************/
%Let Nvars = 3;%*%eval(%sysfunc(countc(%cmpres(&Names.),%str( ),t) +1);
Proc Freq data = &Libname..&Memname;
format &Names.;
by &ByVar.;
tables %sysfunc(tranwrd(&Names.,%str( ), * ))
/ list missing noprint
out = Freq;
DATA &Out_Libname..&Series.Cmb (drop = &Names.);
if 0 then set &Libname..&Memname. (keep = &Names.);%*get var labels;
attrib Comb length = $ %eval(50 * &Nvars.)
label = "Combinations of &Series."
Count length = 4
Percent length = 8;
array Series(&Nvars.) &TypeCn. &TypeLength. &Names.;
array Labels(&Nvars.) $ 48 _temporary_;
retain Comb ' ';
*initialize labels;
do I = 1 to dim(Labels);
Labels(I) = vlabel(Series(I));
if %length(&SeriesChar.) then
Labels(I) = left(
substr(Labels(I),index(Labels(I),"&SeriesChar.")+1));
end;
do until(EndoFile);
set Freq end = EndoFile;
do I = 1 to dim(Series);
if Series(I) eq &True. then
Comb = catx(' ',Comb
,catt(Labels(I),','));
end;
substr(Comb,length(Comb),1) = ' ';*remove trailing comma;
output;
end;
stop;
run;
Proc print data = &Syslast.;
*todo: Export to csv;
proc plan; factors
subject = 10
ordered i=1
ordered / noprint;
treatments
Q01A=1 of 2
Q01B=1 of 2
Q01C=1 of 2;
output
out = work.test;
run;
proc print;
run;
*also: post to SAS-L by Mary H 2008-May-15;
title 'All Combinations of (78 Choose 2) Integers';
ods output Plan=Combinations;
proc plan; factors
block = 3003
ordered
Treat = 2 of 78 comb;
run;
proc print data = Combinations noobs;
run;
/* 78!/(2!78-2!)=3003 */
* posted by data _null_ 2008-May-15;
%let n = 78;
%let r = 2;
%let c = %sysfunc(comb(&n,&r));
%put _user_;
proc plan ordered;
factors c = &c
t = &r of &n
comb;
output out=plan;
run;
quit;
[edit] Expected Output
Fehd: Check All That Apply WORK.CHKALLREPORT Obs Name Names Labels Count Percent 1 Q01 Q01A Q01A 59 59.0000 2 Q01 Q01B Q01B 45 45.0000 3 Q01 Q01C Q01C 53 53.0000 4 Q01 Q01A Q01B Q01C Q01A, Q01B, Q01C 13 14.6067 5 Q01 Q01A Q01B Q01C Q01A, Q01B 10 11.2360 6 Q01 Q01A Q01B Q01C Q01A, Q01C 19 21.3483 7 Q01 Q01A Q01B Q01C Q01A 17 19.1011 8 Q01 Q01A Q01B Q01C Q01B, Q01C 13 14.6067 9 Q01 Q01A Q01B Q01C Q01B 9 10.1124 10 Q01 Q01A Q01B Q01C Q01C 8 8.9888
[edit] References
- %SHOWCOMB: a macro to produce a data set with frequency of
combinations of responses from multiple-response data http://www2.sas.com/proceedings/sugi22/POSTERS/PAPER204.PDF
- %CHECKALL: a macro to produce a frequency of response data
set from multiple-response data http://www2.sas.com/proceedings/sugi22/POSTERS/PAPER236.PDF
--macro maven == the radical programmer 10:00, 8 April 2008 (EDT)
TinyUrl: http://tinyurl.com/5phqzl
Categories: FREQ | PLAN
