Categorical Conjoint Measurement Macro

 /****************************************************************/
 /*          S A S   S A M P L E   L I B R A R Y                 */
 /*                                                              */
 /*    NAME: CANCORR2                                            */
 /*   TITLE: Categorical Conjoint Measurement Macro              */
 /* PRODUCT: IML                                                 */
 /*  SYSTEM: ALL                                                 */
 /*    KEYS: MULTIV REGR                                         */
 /*   PROCS: CANCORR IML PRINT                                   */
 /*    DATA:                                                     */
 /*                                                              */
 /* SUPPORT: WEW                         UPDATE: 06SEP1989       */
 /*     REF:                                                     */
 /*    MISC: TRANSLATED FROM MATRIX TO IML USING MATIML          */
 /*                                                              */
 /****************************************************************/
 %MACRO CCM;
*------------------CATEGORICAL CONJOINT MEASUREMENT---------------+
|                                                                 |
| THE PURPOSE OF CATEGORICAL CONJOINT MEASUREMENT IS TO ASSIGN    |
| NUMERIC VALUES TO EACH CATEGORY OF A CONTINGENCY TABLE SO AS TO |
| MAXIMIZE THE CORRELATION BETWEEN THE RESULTING ROW AND COLUMN   |
| VARIABLES.  THIS IS ACCOMPLISHED BY CANONICAL CORRELATION ON    |
| DUMMY VARIABLES.  THE VALUES ARE GIVEN BY THE RAW COEFFICIENTS  |
| FOR THE FIRST CANONICAL VARIABLES.                              |
|                                                                 |
| THE MACRO ASSUMES THAT YOU HAVE PROVIDED THE CONTINGENCY        |
| TABLE IN THE FORM OF A MATRIX "RC".  THE MACRO COMPUTES A       |
| CORRECTED SSCP MATRIX AND CREATES A DATASET SUITABLE FOR INPUT  |
| TO PROC CANCORR.  YOU MUST ALSO PROVIDE A MATRIX "NAME"         |
| CONTAINING NAMES FOR THE ROW AND COLUMN DUMMY VARIABLES.        |
|                                                                 |
| CATEGORICAL CONJOINT MEASUREMENT IS A SPECIAL CASE OF           |
| CORRESPONDENCE ANALYSIS AND IS CLOSELY RELATED TO THE METHOD    |
| OF RECIPROCAL AVERAGES.                                         |
|                                                                 |
| SEE PP. 290-293 OF MARDIA, KENT & BIBBY: MULTIVARIATE ANALYSIS  |
|                                                                 |
+-----------------------------------------------------------------;
  PRINT RC;

  *------COMPUTE CORRECTED SSCP MATRIX FROM CONTINGENCY TABLE-----;

  R = RC[,+];
  C = RC[+,];
  N = R[+,];
  RR = DIAG(R) - (R*R`)/N;
  CC = DIAG(C) - (C`*C)/N;
  RC = RC  - (R*C)/N;
  sscp  =  (RR || RC) // (RC` || CC);

  * THE SSCP MATRIX IS NOW:   | RR  RC |
                              | RC` CC |  ;

  *------CREATE AN OUTPUT DATA SET WITH NO. OF OBSERVATIONS AND
        THE CORRECTED SSCP MATRIX--------------------------------;

  NRC = NROW(sscp);
  int = J({1},NRC,0);
  sscp=(n||int)//(int`||sscp);
  Nobs = J({1},ncol(sscp),N);
  X  = Nobs // sscp;
  NAME={ 'INTERCEP'} || NAME;
  RNAME = { ' '} || NAME;
  CREATE CCMDATA (RENAME=(RNAME  =_NAME_  ))
         FROM X [ROWNAME=RNAME COLNAME=NAME ];
  APPEND FROM X [ROWNAME=RNAME];
  QUIT;

 DATA CCMDATA(TYPE=SSCP); SET CCMDATA;
     IF _N_ = 1 THEN _TYPE_ = 'N   ';
     ELSE _TYPE_ = 'SSCP';
 run;

 PROC PRINT; run;
 %mend;

 *----------------------------------------------------------------+
 | DATA FROM GLASS(1954), SOCIAL MOBILITY IN BRITAIN,             |
 |   ROUTLEDGE & KEGAN                                            |
 |      ROW CATEGORIES ARE FATHER'S SOCIAL STATUS.                |
 |      COLUMN CATEGORIES ARE SON'S SOCIAL STATUS.                |
 +----------------------------------------------------------------;
 PROC IML;
 TITLE 'CATEGORICAL CONJOINT MEASUREMENT BY CANONICAL CORRELATION';
 TITLE2 'EXAMPLE 1';
  RESET AUTONAME ;

  *------SET UP CONTINGENCY TABLE------;

  RC ={ 50  45  8  18  8,
        28 174  84 154  55,
        11  78 110 223  96,
        14 150 185 714 447,
         0  42  72 320 411};
  NAME ={ 'F1' 'F2' 'F3' 'F4' 'F5' 'S1' 'S2' 'S3' 'S4' 'S5'};
 %CCM

 *------THE CATEGORIES ARE SCALED BY OBTAINING THE CANONICAL
        COEFFICIENTS FOR THE FIRST CANONICAL VARIABLE-------------;

 PROC CANCORR DATA=CCMDATA NCAN=1 SIMPLE CORR outstat=outst
      VNAME = 'DUMMY VARIABLES FOR FATHER''S STATUS'
      WNAME = 'DUMMY VARIABLES FOR SON''S STATUS'
      ;
      VAR  F2 F3 F4 F5 F1;
      WITH S2 S3 S4 S5 S1;
 run;
 proc print data=outst;
   where _TYPE_ = 'RAWSCORE';
 run;
  *---------------------------------------------------------------;

 PROC IML;
   TITLE2 'EXAMPLE 2';
   RESET AUTONAME ;
   RC ={  8 4 2 1 0 0,
          4 8 4 2 1 0,
          2 4 8 4 2 1,
          1 2 4 8 4 2,
          0 1 2 4 8 4,
          0 0 1 2 4 8};
   NAME ={ 'R1' 'R2' 'R3' 'R4' 'R5' 'R6'
           'C1' 'C2' 'C3' 'C4' 'C5' 'C6'};
 %CCM

 PROC CANCORR DATA=CCMDATA NCAN=1 SIMPLE CORR outstat=outst
      ;
      VAR  R1-R6;
      WITH C1-C6;
 run;
 proc print data=outst;
   where _TYPE_ = 'RAWSCORE';
 run;
 *;





 *-------------ANOTHER METHOD------------------------------------;
 %MACRO CCM2;
          *---CATEGORICAL CONJOINT MEASUREMENT NO. 2--------------;
 *** NOTE: A FREQ statement must be used with PROC CANCORR,
           i.e, FREQ freq;
     PRINT RC;
     NR = NROW(RC);
     NC = NCOL(RC);
     X = SHAPE(RC,0,{1}) || DESIGN( ({1}:NC)`@ J(NR,{1},{1}))
                         || DESIGN( J(NC,{1},{1})@({1}:NR)`);
     CNAME ={ 'FREQ'};
     CNAME = CNAME || NAME;
     _TMP_ROW = 'ROW1    ' : compress('ROW'+char(nrow(X)));
     CREATE CCMDATA ( RENAME=(_TMP_ROW=ROW  ))
            FROM X [ROWNAME=_TMP_ROW COLNAME=CNAME ];
     APPEND FROM X [ROWNAME=_TMP_ROW];
     QUIT;
   PROC PRINT;
   RUN;
 %MEND;

 PROC IML;
 TITLE 'CATEGORICAL CONJOINT MEASUREMENT BY CANONICAL CORRELATION';
 TITLE2 'EXAMPLE 1: ANOTHER METHOD';
   RESET AUTONAME ;

   *------SET UP CONTINGENCY TABLE------;

   RC ={ 50  45  8  18  8,
         28 174  84 154  55,
         11  78 110 223  96,
         14 150 185 714 447,
          0  42  72 320 411};
   NAME ={ 'F1' 'F2' 'F3' 'F4' 'F5' 'S1' 'S2' 'S3' 'S4' 'S5'};
 %CCM2

 *------THE CATEGORIES ARE SCALED BY OBTAINING THE CANONICAL
        COEFFICIENTS FOR THE FIRST CANONICAL VARIABLE-------------;

 PROC CANCORR DATA=CCMDATA NCAN=1 SIMPLE CORR outstat=outst
      VNAME = 'DUMMY VARIABLES FOR FATHER''S STATUS'
      WNAME = 'DUMMY VARIABLES FOR SON''S STATUS'
      ;
      VAR  F2 F3 F4 F5 F1;
      WITH S2 S3 S4 S5 S1;
      FREQ freq;
 run;

 proc print data=outst;
   where _TYPE_ = 'RAWSCORE';
 run;
title;title2;