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