As the first step in the decommissioning of sasCommunity.org the site has been converted to read-only mode.


Here are some tips for How to share your SAS knowledge with your professional network.


Processing Check-All-That-Apply

From sasCommunity
Jump to: navigation, search

TinyUrl: http://tinyurl.com/5phqzl

Author: Ronald_J._Fehd

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.

Example Data

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;

New and Improved CheckAll

Here are the routine and a caller program:

  1. ProcFreq2Comb
  2. ProcFreq2Comb-caller

Routine: ProcFreq2Comb

*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;

ProcFreq2Comb-caller.sas

%Let Libname = Library;
%Let Memname = MyData;
%Let Names   = Q01A Q01B Q01C;
 
%Let Series  = Q01;*output data set name;
%Let SeriesChar = ;*none;
 
%Let True    = 'Y';*char: Y/N;
%Let TypeCn  = $;*char;
%Let TypeLength = 1;*char1 for 'Y';
 
%Let Out_Libname = Work;
%Include ‘ProcFreq2comb.sas’;

Alternatives: Proc Plan

Here are SAS-L contributtions.

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;

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

References

-- created by User:Rjf2 10:00, 8 April 2008 (EDT)

--Ronald_J._Fehd macro.maven == the radical programmer