/* macro to test for DIF using logistic regression techniques %lrdif(data=chh.ny, items=it10-it18, exo=kt reynell, outfile=results, plot=NO); the data set 'data' contains the 'items' coded 0,1, .. , the exogenous variables 'exo' and the results are written to the data set 'outfile' */ %macro lrdif(data, items, exo, outfile=LRDIF, plot=NO); options nonotes nomprint; /* save number of respondents as macro variable */ data _null_; set &data end=final; if final then call symput('N',trim(left(_N_))); run; /* save the item names as macro variables */ data _null_; set &data; array _y (*) &items; length name $8; if _n_=1 then do; do _i=1 to dim(_y); call vname(_y{_i}, name); call symput('_item'||trim(left(put(_i,4.))),trim(left(name))); end; _p=dim(_y); call symput('_nitems',trim(left(put(_p,4.)))); end; run; /* calculate number of exogenous variables - save names as macro variables */ data _null_; set &data; array _y (*) &exo; length name $8; if _n_=1 then do; do _i=1 to dim(_y); call vname(_y{_i},name); call symput('_exo'||trim(left(put(_i,4.))),trim(left(name))); end; _p=dim(_y); call symput('_nexo',trim(left(put(_p,4.)))); end; run; /* write something on the screen */ %put -----------------------------------------------------------; %put logistic regression tests for differential item functioning; %put -----------------------------------------------------------; %put reading &N cases from data set &data, ; %put &_nitems items, &_nexo exogenous variables ; %put -----------------------------------------------------------; /* complete data set compute score */ data _new; set &data; _score=0 %do _i=1 %to &_nitems; +&&_item&_i %end;; run; /* loop over (item, exo) combinations */ %do _i=1 %to &_nitems; %do _e=1 %to &_nexo; /* direct output to file */ ods output logistic.parameterestimates=_pf&_i.&_e; ods listing close; /* run analysis */ proc logistic data=_new; class _score; model &&_item&_i=_score &&_exo&_e /* _score*&&_exo&_e */; run; ods listing; /* title "item &&_item&_i"; proc print data=_pf&_i.&_e(where=(variable="&&_exo&_e") rename=(probchisq=p) keep=variable Estimate StdErr probchisq) noobs; run; */ data &outfile.&_i.&_e; set _pf&_i.&_e (where=(variable="&&_exo&_e")); item="&&_item&_i "; keep item variable Estimate StdErr probchisq; run; %end; %end; /* create output file */ data &outfile; set %do _i=1 %to &_nitems; %do _e=1 %to &_nexo; &outfile.&_i.&_e %end; %end;; run; title ' '; /* create plots if required */ %if %upcase(%left(%trim(&plot)))=YES %then %do; %put plotting mean item scores for the exogenous variables; %put ---------------------------------------------------------; %do _e=1 %to &_nexo; %do _it=1 %to &_nitems; proc sort data=_new; by _score; run; proc means data=_new(where=(&&_exo&_e=0)) noprint mean; var &&_item&_it; by _score; output out=_plot0 mean=mean0 lclm=lclm0 uclm=uclm0; run; proc means data=_new(where=(&&_exo&_e=1)) noprint mean; var &&_item&_it; by _score; output out=_plot1 mean=mean1 lclm=lclm1 uclm=uclm1; run; data _plot0; set _plot0; if _FREQ_<20 then do; lclm0=.; uclm0=.; end; run; data _plot1; set _plot1; if _FREQ_<20 then do; lclm1=.; uclm1=.; end; run; data _plot; merge _plot0 _plot1; by _score; label lclm0=' '; label uclm0=' '; label mean0='Mean score'; label lclm1=' '; label uclm1=' '; label mean1='Mean score'; label _score='Total score'; run; title2 justify=center "Responses to item &&_item&_it for the two &&_exo&_e groups:"; title3 justify=center "Mean scores and 95% confidence interval"; symbol1 v=star c=blue i=none; symbol2 v=none c=blue i=join l=20; symbol3 v=none c=blue i=join l=20; symbol4 v=star c=red i=none; symbol5 v=none c=red i=join l=20; symbol6 v=none c=red i=join l=20; legend1 position=center; proc gplot data=_plot; plot (mean0 lclm0 uclm0 mean1 lclm1 uclm1)*_score/overlay legend=legend1; run; quit; %end; %end; /* end of fit test part*/ %end; /* clean up */ proc datasets nolist; delete %do _i=1 %to &_nitems; %do _e=1 %to &_nexo; &outfile.&_i.&_e _pf&_i.&_e %end; %end; _new; run; quit; title ' '; ods listing; options notes stimer; %mend;