Factor analysis of Dichotomous Items

/*
http://support.sas.com/onlinedoc/913/getDoc/en/statug.hlp/factor_sect22.htm
http://support.sas.com/ctx/samples/index.jsp?sid=512
*/
/*place a SAS macro somewhere in your PC*/

%let dataname=amy;
%let name_of_doc=xxxxx\tetra_result.txt;

%include "xxxxxxxxxxxxx\sample00512_1_polychor.sas";

data raschdata;
set &dataname;
run;

data raschdata2;
set raschdata;
xxx=.;
keep
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

;
run;

%let abc=&syslast;
data _null_;set &abc end=end;
array test (*) _numeric_; array allmiss (3000) $ (3000*'true');
length list $ 5000; do i=1 to dim(test); if test(i) ne . then allmiss(i)='false';
end; if end=1 then do i= 1 to dim(test);
if allmiss(i) ='true' then list=trim(list)||' '||trim(vname(test(i)));
end; call symput('mlist',list);
run;
data &abc ; set &abc ; drop &mlist;run;
PROC SQL NOPRINT;
SELECT TRIM(NAME)
INTO :VARLIST SEPARATED BY ' '
FROM DICTIONARY.COLUMNS
WHERE LIBNAME EQ "WORK" AND MEMNAME EQ "RASCHDATA2"
ORDER BY VARNUM;
QUIT;

proc means data=raschdata2 ;
output out=meanresult;
var &varlist;
run;

data meanresult2;
set meanresult;
if _stat_="STD";
array kazu _numeric_ ;
do over kazu;
if kazu=0 then kazu=.;
end;
xxx=.;
run;
%let abc=&syslast;
data _null_;set &abc end=end;
array test (*) _numeric_; array allmiss (3000) $ (3000*'true');
length list $ 5000; do i=1 to dim(test); if test(i) ne . then allmiss(i)='false';
end; if end=1 then do i= 1 to dim(test);
if allmiss(i) ='true' then list=trim(list)||' '||trim(vname(test(i)));
end; call symput('mlist',list);
run;
data &abc ; set &abc ; drop &mlist _freq_ _stat_;run;

PROC SQL NOPRINT;
SELECT TRIM(NAME)
INTO :VARLIST SEPARATED BY ' '
FROM DICTIONARY.COLUMNS
WHERE LIBNAME EQ "WORK" AND MEMNAME EQ "MEANRESULT2"
ORDER BY VARNUM;
QUIT;

%polychor(data=raschdata,var=&varlist,maxiter=200,out=result);

/*just to get the name first*/
data result2;
retain _name_;
set result;
run;

PROC EXPORT DATA= result2 OUTFILE= "C:\temp\matrix.xls"
DBMS=EXCEL2000 REPLACE;
RUN;

option NOCENTER;
PROC PRINTTO PRINT="&name_of_doc" new;
RUN;
options formdlim=' ';

data one (type=corr);
set result2;
run;

proc factor data=one
method=prinit
n = 2
rotate = v
scree;
*where _type_="CORR";
var &varlist
;
run;

proc factor data=one
method=prin priors=smc
n = 2
rotate = v
scree;
var
&varlist
;
run;

PROC PRINTTO PRINT=PRINT;
run;
quit;

x "notepad &name_of_doc";