T-Square Chart for Bivariate Process Data

 /****************************************************************/
 /*          S A S   S A M P L E   L I B R A R Y                 */
 /*                                                              */
 /*    NAME: SHWTSQ                                              */
 /*   TITLE: T-Square Chart for Bivariate Process Data           */
 /* PRODUCT: QC                                                  */
 /*  SYSTEM: ALL                                                 */
 /*    KEYS: Shewhart Charts, T-Square Charts,                   */
 /*   PROCS: SHEWHART CORR MEANS                                 */
 /*    DATA:                                                     */
 /*                                                              */
 /*     REF: SAS/QC Software:  Examples                          */
 /*    MISC:                                                     */
 /*                                                              */
 /****************************************************************/

options ps=60 ls=80;


data fibers;
   n=10;
   do sample=1 to 10;
      do i=1 to n;
         x=rannor(15341);
         y=0.7 + rannor(32351);
         x=0.1*x  + 112;
         y=0.08*y + 1;
         output;
         end;
      end;
   n=5;
   do sample=11 to 15;
      do i=1 to n;
         x=rannor(15341);
         y=0.7 + rannor(32351);
         x=0.1*x  + 112;
         y=0.08*y + 1;
         output;
         end;
      end;
   n=12;
   do sample=16 to 20;
      do i=1 to n;
         x=rannor(15341);
         y=0.7 + rannor(32351);
         x=0.1*x  + 112;
         y=0.08*y + 1;
         output;
         end;
      end;
   n=15;
   do sample=21 to 30;
      do i=1 to n;
         x=rannor(15341);
         y=0.7 + rannor(32351);
         x=0.1*x  + 112;
         y=0.08*y + 1;
         output;
         end;
      end;
run;

title 'Bivariate Process Data';
proc print data=fibers noobs label;
   var x y;
   id sample;
   label x = 'Strength'
         y = 'Diameter' ;
run;
title;

proc corr data=fibers noprint outp=summary cov;
   var x y;
   by sample;
run;

data means;
   keep sample avgx avgy;
   set summary;
   if _TYPE_='MEAN' then do;
      avgx = x; avgy = y; output;
      end;
run;

data varx;
   keep sample varx;
   set summary;
   if _TYPE_='COV' & _NAME_='x' then do; varx = x; output; end;
run;

data vary;
   keep sample vary;
   set summary;
   if _TYPE_='COV' & _NAME_='y' then do; vary = y; output; end;
run;

data covxy;
   keep sample covxy;
   set summary;
   if _TYPE_='COV' & _NAME_='x' then do; covxy = y; output; end;
run;

data samplen;
   keep sample n;
   set summary;
   if _TYPE_='N' then do; n = x; output; end;
run;

data all;
   merge means varx vary covxy samplen;
   by sample;
run;

proc means data=all noprint;
   var avgx avgy varx vary covxy;
   weight n;
   output out=avgs mean=mavgx mavgy mvarx mvary mcovxy;
run;

data tsquare;
   length _VAR_ $ 8 ;
   keep _SUBN_ _LIMITN_ _SUBX_
         _LCLX_ _MEAN_ _UCLX_ _ALPHA_ _VAR_ sample;
   set all;
   if _n_=1 then set avgs;
   _ALPHA_ = 0.10;
   _SUBN_ = n;
   _LIMITN_ = n;
   constant = mvarx * mvary - mcovxy * mcovxy ;
   _SUBX_ = mvary * (avgx - mavgx)**2 +
            mvarx * (avgy - mavgy)**2 -
            2.0 * (avgx - mavgx)*(avgy - mavgy)*mcovxy ;
   _SUBX_ = _SUBX_ / constant;
   _LCLX_ = 0.0 ;
   _MEAN_ = 2 * ( 30 - 1 ) * ( _SUBN_ - 1 ) /
             ( _SUBN_ * ( 30 * _SUBN_ - 30 - 2 + 1 ) );
   _MEAN_ = _MEAN_ * ( 30 * _SUBN_ - 30 - 2 + 1 ) /
                     ( 30 * _SUBN_ - 30 - 2 + 1 - 2 );
   _UCLX_ = 2 * ( 30 - 1 ) * ( _SUBN_ - 1 ) ;
   _UCLX_ = _UCLX_ /
             ( _SUBN_ * ( 30 * _SUBN_ - 30 - 2 + 1 ) );
   _UCLX_ = _UCLX_ * FINV( 1 - _ALPHA_ ,
                           2,
                           30*_SUBN_ - 30 -2 + 1 );
   _VAR_ = 'tsquare';
   run;

symbol1 v=dot c=white h=.75;
title 'Multivariate Control Chart';
proc shewhart table=tsquare;
   xchart tsquare * sample /
     cframe  = gray
     xsymbol = 'E(T Square)'
     cinfill = blue
     novangle;
label _SUBX_ = 'T Square'
      sample = 'Sample Number';
run;

goptions reset=all;