%macro ordalph(ds=,items=);

*************************************************************;
data itemdata;
set &ds(keep=&items); 

%let qitems=q1-q&nitems;

if nmiss(of &qitems) =0; /* use listwise deletion*/ 
totscore= sum(of &qitems);
label totscore = "Overall Score"; 
keep totscore &qitems;
run;

* get sampsize for use later on;
proc sql noprint;
	select count(*) into :sampsize
	from itemdata;
quit;
*------------------------------------------------------------;

*------------------------------------------------------------;
TITLE "&ds: Pearson correlation matrix"; run;
proc corr data=itemdata outp=pearsonc alpha noprob nosimple; 
	var &qitems;
run;
proc print data=pearsonc(where=(_type_="CORR")) noobs label ; 
var _name_ &qitems;
format &qitems 5.3; 
label _name_ ="item";
run;

ods exclude all; 
proc freq data=itemdata ;
tables (&qitems)*(&qitems) /plcorr noprint ;
ods output measures=mycorr (where=(statistic="Tetrachoric Correlation"
                                or statistic="Polychoric Correlation") 
                            keep = statistic table value);
run;
ods exclude none;
*------------------------------------------------------------;

*------------------------------------------------------------;
data mycorr; 
	set mycorr;
x = scan(table, 2, " *"); 
y = scan(table, 3, " *"); 
group=substr(y,2)+0;
run;

proc sort data=mycorr; 
	by group x;
	
proc transpose data = mycorr out=polycorr (drop = group _name_)	;
id x;	 
by group;	 
   var value ;	 
run;	 

data polycorr(type=corr);	 
   _TYPE_='CORR';	 
     set polycorr end=endc;	 
     _name_=compress("q"||put(_n_,2.));	 
     output;	 
     array q _numeric_;	 
     if endc then do;	 
       _TYPE_='N';	 
         do over q;	 
           q=&sampsize; 	 
           end;	 
       output;	 
       end;	 
run;

TITLE "&ds: Polychoric correlation matrix"; run;
proc print data = polycorr(where=(_type_="CORR")) noobs label; 
	var _name_ &qitems;
label _name_ ="item"; 
format &qitems 5.3; 
run;
*------------------------------------------------------------;

*------------------------------------------------------------;
TITLE "&ds: Factor Analysis on Polychoric matrix"; run;
/* do Factor Analysis on the Correlation Matrix */
proc factor data=polycorr method=ml nfactors=1 plots=all; 
run;
*------------------------------------------------------------;

/* calculate alpha and omega and store it in a data set */
%macro varlist;
%do i = 1 %to &nitems; 
	q&i
%end;
%mend;

%macro calcalpha(qs=q, cordat=polycorr, out=alpha); 
/* qs= the subsection of the instrument */
/* cordat is the correlation matrix data */ 

TITLE "&ds: IML input=&cordat"; run;
proc iml;
     use &cordat(where=(_type_="CORR")) var {%varlist}; 
     read all var {%varlist } into itemcor; 
     section="&qs";
     datused="&cordat"; 
     numbitem=trace(itemcor); 
     one=j(numbitem,1);
     print 'The Input Correlation'; 
     print itemcor;
     print 'Number of items' numbitem; 
     sumcor=(one`)*itemcor*one; /*sum all correlations*/ 
     alpha=(numbitem/(numbitem-1))*(1-(numbitem / sumcor)); 
     print alpha;
     L = eigval(itemcor); 
     theta=(numbitem/(numbitem-1))*(1-1/L[1]); 
     print 'Theta';
     print theta;
     /* to save results in a data set */
     create &out var {section datused alpha theta}; 
                            /** create data set **/
     append;	/** write data **/
     close &out;	/** close the data set **/
quit;	 
run;	 
%mend;	 
********************************************************;

*********************************;
%calcalpha(qs=q, cordat=pearsonc, out=alphap);
%calcalpha(qs=q, cordat=polycorr);
************************************************;

*close support files;
ods pdf close;

quit;

%mend ordalph;
*************************************************************************;
*                             End of Program                            *;
*************************************************************************;