cϽ 1""2"2""2"22""SAS FILESASMACR CATALOG 7!gA7!gA $9.0101M3XP_PRO7!{N{N{N7!gA xG#ڃAڃAF123n    G$ڃAڃAF 124n  @ 0     J ڃAڃAE66on  G!ڃAڃAF 121n    J;DڃADڃAM 205nGDڃAڃAESYSRESR PGBITMAPXMACRO IRT_LOCALDEP| MACRO IRTFIT_THETA MACRO IRTFIT_SUM MACRO IRTFIT_GRAPHP MACRO IRTFIT$ MACRO C_ICCXLCH,$ (XLSR71gA71gA  XLSRzLgAzLgA F F  XLSR@gAKgA:  F  XLSR OgAOgAvQ F  XLSR gAgA\2p F  XLSRR>ϳgAR>ϳgAE>8 F  XLSRDgADgAh,2 F  XLSRxQgAxQgA eK4 $F  jj``  "tIRTFITC9.1  >"0ITEMLIST"5DATA_NONE"5PARFILE_NONE"4MODELREAD"4 TESTMETHODNONE"2LD_TESTNO"8SCALESUBTOTAL"1D1"1MIN_PRE5"2RESCALENO"4CRITCUT0.02"4FITBOUND2.02"2 SAMPLETESTNO"3N_REP100"2SEED-1"2GRAPHNO"4 GRAPH_DATANONE"4OUTLIBNONE"7OUTPUTLIMITED"4OUTCORE_IRT"3OUTFMTWIN"1P_MEAN0"1P_STD1"2LOWRNG-5"1HIGHRNG5"3INTV_SUM0.1"3 INTV_THETA0.5"1MINCODE1"1MISSING."1 MAXCHOICE7"v ods exclude all; options nonotes nostimer nomprint nosymbolgen nomlogic; *options mprint symbolgen; *options mprint;"qa"%trim(%left(%upcase(&data)))"= "_NONE" and (%upcase(&testmethod)^=NONE or %upcase(&LD_test)^=NO)"@0***** ERROR: A data set must be specified *****"EXIT" ;""td"%trim(%left(%upcase(&parfile)))"= "_NONE" and (%upcase(&testmethod)^=NONE or %upcase(&LD_test)^=NO)"P@***** ERROR: An item parameter file set must be specified *****"EXIT" ;""iY%upcase(&testmethod)^= NONE and %upcase(&testmethod)^=THETA and %upcase(&testmethod)^=SUM"^N***** ERROR: TESTMETHOD must be specified as either NONE, THETA, or SUM *****"EXIT" ;""B2%upcase(&testmethod)=NONE and %upcase(&LD_test)=NO"OUTPUT"""t************************************************ IRTFIT ANALYSES ************************************************""&DATA ne _NONE"G7THE DATA SET (ITEM RESPONSES) IS: &DATA""!&PARFILE ne _NONE"J:THE ITEM PARAMETER FILE IS: &PARFILE""&%UPCASE(&MODEL) = READ"B2THE IRT MODEL IS READ FROM THE ITEM PARAMETER FILE""H8THE IRT MODEL IS: &MODEL"D4THE D CONSTANT IS SET AT: &D"J:THE ITEMS ARE ASSUMED TO HAVE A MINIMUM SCORE OF: &MINCODE"L<THE MAXIMAL NUMBER OF RESPONSES CHOICES ARE: &MAXCHOICE"(%UPCASE(&OUTLIB) NE NONE"=-OUTPUT FILES ARE SAVED IN THE LIBRARY &OUTLIB""bRTHE OUTPUT FILE NAMES ARE: &OUTCORE._FREQ AND &OU TCORE._FIT"'%UPCASE(&LD_test) = YES"RB_ AND &OUTCORE._LD""&%UPCASE(&OUTFMT) = WIN"8(OUTPUT IS SHOWN IN THE SAS OUTPUT WINDOW""&%UPCASE(&OUTFMT) = PDF",OUTPUT IS SENT TO A PDF FILE""&%UPCASE(&OUTFMT) = RTF"-OUTPUT IS SENT TO AN RTF FILE""TDTHE SAMPLE MEAN AND SD IS ASSUMED TO BE: &P_MEAN AND &P_STD"UETHE QUADRATURE POINT RANGE IS: &LOWRNG TO &HIGHRNG",%UPCASE(&TESTMETHOD) = THETA"M=THE STEPSIZE IS: &INTV_THETA"VFIRT FIT TESTS ARE BASED ON THE X2* and G2* FIT STATISTICS (STONE 2000)"\LTHE FIT STATISTICS ARE CALCULATED BASED ON THE RANGE -&FITBOUND TO &FITBOUND"\LCELLS WITH PREDICTED VALUES BELOW &CRITCUT ARE EXCLUDED FROM THE CALCULATION"*%UPCASE(&SAMPLETEST) = YES"aQP-VALUES ARE CALCULATED THROUGH A MONTE-CARLO RESAMPLE PROCEDURE (&N_REP SAMPLES)"""*%UPCASE(&TESTMETHOD) = SUM"K;THE STEPSIZE IS: &INTV_SUM"dTIRT FIT TESTS ARE BASED ON THE S-X2 and S-G2 FIT STATISTICS (ORLANDO & THISSEN 2000)"*%UPCASE(&SCALE) = SUBTOTAL"sITEM RESPONSE PROBABILITIES ARE CONDITIONED ON THE SIMPLE SUM OF ALL ITEMS IN THE SCALE EXCEPT THE ITEM IN QUESTION""'%UPCASE(&SCALE) = TOTAL"gWITEM RESPONSE PROBABILITIES ARE CONDITIONED ON THE SIMPLE SUM OF ALL ITEMS IN THE SCALE""J:THE MINIMAL PREDICTED CELL VALUE IS: &MIN_PRE"""u*********************************************************************************************************************"" data _null_; array _it (*) &itemlist; call symput('n_it1', left(dim(_it))); run; data _null_; set &data end=last; array _it (*) &itemlist; array _n (&n_it1); retain _n1-_n&N_it1 0; do i=1 to &n_it1; if _it[i]^=. then _n[i]=1; end; if last then do;" length itemname $16; do i=1 to &n_it1; call symput('use' || left(i), _n[i]); call vname(_it[i], itemname); call symput('_it' || left(i), upcase(itemname) ); end; end; run;"USEDITEM" " NOTUSEDITEM" "NITEMS" 0"%I1&n_it11" &&use&i=1"NITEMS" %eval(&nitems+1)"USEDITEM"& &usedItem   &&_it&i"" NOTUSEDITEM"6 &&NotUsedItem   %scan(&itemlist, &i)""&NotUsedItem^="\LThe following items do not have observations in &data and will not be used -" &NotUsedItem"" data _par; length model $10; set &parfile end=last; array _it (*) &UsedItem; array _n (&nitems); retain _n1-_n&nitems 0; length itemname $16; retain used 0; do i=1 to &nitems; call vname(_it[i], itemname); if upcase(name)=upcase(itemname) then do;"  used+1; _n[i]=1; end; end; ******************************************************************************** Rename and recalculate item parameters ****************************************************************************" ****; array thresholds (&maxchoice) threshold1-threshold&maxchoice "tC_ICCC9.1  9>"0MODEL"0_THETA"0_ITNO"3_ITSCOALL"MA *options mprint mlogic notes stimer symbolgen; *options mprint;"p`%upcase(&model) = GPCM | %upcase(&model) = PCM | %upcase(&model) = GRSM | %upcase(&model) = RSM"  *******************************************************************; *; * ICC for the Generalized Partial Credit Model * first we calculate the denominator, * which is common for all response choices *; **********************************" *********************************; divisor=1; do __i=1 to (symget("itch&_itno")-1); sum=0; do __j=1 to __i; sum=sum+symget("st&_itno._"||left(__j)); end; divisor=divisor+exp(&&itsl&_itno*(__i*&_theta-sum))" ; end;"'%upcase(&_itsco) ne ALL"  *******************************************************************; *; * Calculate the icc for the relevant response choice *; **********************************************************"*********; if &_itsco = &mincode then icc&_itno=1/divisor; else if &_itsco = . then icc&_itno=1; else do; sum2=0; do __j=1 to (&_itsco -1); sum2=sum2+"symget("st&_itno._"||left(__j)); end; icc&_itno=exp(&&itsl&_itno*((&_itsco-&mincode)*&_theta-sum2)) /divisor; end;"" *******************************************************************; * Calculate icc for all response choices *******************************************************************; icc1=1/divisor;" array icc_a&_itno (*) icc1-icc&&itch&_itno; do __i=2 to &&itch&_itno; sum2=0; do __j=1 to __i-1; sum2=sum2+symget("st&_itno._"||left(__j)); end;"rf icc_a&_itno(__i)=exp(&&itsl&_itno*((__i-1)*&_theta-sum2))/divisor; end;"8"%%upcase(&model) = NOM" **************************************************************************; * ICC for the Nominal Categories Model **************************************************************************; divisor=1; do __i=1 to (symget("itch&_itno")-1);"{o divisor=divisor+exp(symget("itsl&_itno._"||left(__i))*&_theta + symget("int&_itno._"||left(__i))); end;"'%upcase(&_itsco) ne ALL" if &_itsco = &mincode then icc&_itno=1/divisor; else if &_itsco = . then icc&_itno=1; else icc&_itno=exp(symget("itsl&_itno._"||left(&_itsco-&mincode))*&_theta + symget("int&_itno._"||left(&_itsco-&mincode))) /divisor;"" array icc_a&_itno (*) icc1-icc&&itch&_itno; icc1 = 1/divisor; do __i=2 to symget("itch&_itno"); icc_a&_itno(__i)=exp(symget("itsl&_itno._"||left(__i-1))*&_theta+symget("int&_itno._"||left(__i-1)))/ divisor;" end;"8"%+%upcase(&model) = GRM" *******************************************************************; * ICC for the Graded Response Model *******************************************************************;"'%%upcase(&_itsco) ne ALL" **************************************************************** ERRO***; *; * Calculate the icc for the relevant response choice *;" *******************************************************************; if &_itsco = . then icc&_itno = 1; else do; __i = &_itsco-&mincode+1;" __j = __i-1; if __i = &&itch&_itno then icc&_itno = 1/(1+exp(-&&itsl&_itno*(&_theta-symget("st&_itno._" || trim(left(__j))) )));" else if __i = 1 then icc&_itno = 1-1/(1+exp(-&&itsl&_itno*(&_theta-&&st&_itno._1))); else icc&_itno = 1/(1+exp(-&&itsl&_itno*(&_theta-symget(""st&_itno._" || trim(left(__j))) ))) -1/(1+exp(-&&itsl&_itno*(&_theta-symget("st&_itno._" || trim(left(__i))) ))); end;"*"  *******************************************************************; * Calculate icc for all response choices *******************************************************************; array icc_a&_itno (*)"  icc1-icc&&itch&_itno; array cicc_a&_itno (*) cicc1-cicc&&itch&_itno; do __i=&&itch&_itno to 1 by -1; __j=__i-1; if __i = &&itch&_itno then do; icc_a&_itno(__i) = 1/(1+exp(-"&&itsl&_itno*(&_theta- symget("st&_itno._"||left(__j))))); cicc_a&_itno(__i) = 1/(1+exp(-&&itsl&_itno*(&_theta- symget("st&_itno._"||left(__j))))); end;" else if __i = 1 then icc_a&_itno(__i) = 1 - cicc_a&_itno(__i+1); else do; icc_a&_itno(__i) = 1/(1+exp(-&&itsl&_itno*(&_theta- symget("st&_itno._"||left(__j))))) - cicc_a"&_itno(__i+1) ; cicc_a&_itno(__i) = 1/(1+exp(-&&itsl&_itno*(&_theta- symget("st&_itno._"||left(__j))))); end; end;"8"18!%upcase(%substr(&model,1,2)) = DI" *******************************************************************; * ICC for the Dichotomously Scored Model *******************************************************************;"'5%upcase(&_itsco) ne ALL"  *******************************************************************; *; * Calculate the icc for the relevant response choice *; ************************************************************"*******;"3 &_itsco = ."' icc&_itno = 1;"4" icc&_itno=&&itgu&_itno + (1-&&itgu&_itno)/(1+exp(-&&itsl&_itno*(&_theta-&&st&_itno._1))); if &_itsco=&mincode then icc&_itno=1-icc&_itno;"7" *******************************************************************; *; * Calculate icc for all response choices *; *******************************************************************; array icc_a&_itno (*) icc1-icc&&itch"&_itno; icc2=&&itgu&_itno + (1-&&itgu&_itno)/(1+exp(-&&itsl&_itno*(&_theta-&&st&_itno._1))); icc1=1-icc2;"8"#90`, @ h p   , 0 H \ Dl`dT\4HT`dBl<PHp|l ERRO ; array steps (&maxchoice) step1-step&maxchoice; array categories (&maxchoice) category1-category&maxchoice; do i = 1 to (choices-1); if thresholds(i) = . and steps(i)^= . then thresholds(" i) = steps(i); else if thresholds(i) = . and location^= . then do; thresholds(i) = location-categories(i); if choices = 2 then thresholds(i) = location; end; end; if slope= . then slope=1; if guess= . then guess=0; if last then do; call symput("nb'used', used); do i=1 to &nitems; call symput('use' || left(i), _n[i]); end; end; run;" &used<&nitems"L<Macro stops because following item(s) do not have parameters"&I1&nitems1" &&use&i=0"$%scan(&usedItem, &i)"""""  ****************************************************************************************** * For RSM and GRSM models calculate number of category parameters to be estimated ****************************************************************************"**************;"_MRPARS" 0"  data _null; set _par (where= (upcase(trim(left(model))) = 'RSM' or upcase(trim(left(model))) = 'GRSM')) end=last; array thresholds (&maxchoice) threshold1-threshold&maxchoice; array categories (&maxchoice) category1-category&maxchoice; location = mean(" of threshold1-threshold&maxchoice); retain _npars (0); _nratingi = _N_; _unequal = 0; do _i = 1 to choices-1; Categories(_i) = location - thresholds(_i); if lag1(categories(_i)) = . or abs(categories(_i) - lag1(categories(_i)) ) > 0.001 then _unequal = 1;" end; _npars = _npars + (choices-1)*_unequal; if last then do; _mpars = _npars/_nratingi; call symput('_mrpars', trim(left(_mpars)) ); end; run;" _MODELCHECK" OK"  data __par; length itemname $12 model $10 slope guess threshold1-threshold&maxchoice slope1-slope&maxchoice intercept1-intercept&maxchoice 8; set _par end=last; array _it (*) &UsedItem; array thresholds (&maxchoice) threshold1-threshold&maxchoice" ; array slopes (&maxchoice) slope1-slope&maxchoice; array intercepts (&maxchoice) intercept1-intercept&maxchoice; retain _maxchoice 0; do i=1 to &nitems; call vname(_it[i], itemname); if trim(upcase(name))=trim(upcase(itemname)) then do;"  call symput('_it'||trim(left(put(i,4.))), trim(left(upcase(name)))); if model='' then model = "&model"; model=trim(left(upcase(model))); if model = 'READ' then call symput('_modelcheck',"  'MISSING'); if model ^= 'GRM' and model ^= 'GPCM' and model ^= 'PCM' and model ^= 'GRSM' and model ^= 'RSM' and model ^= 'NOM' and model ^= 'DI1P'"  and model ^= 'DI2P' and model ^= 'DI3P' then call symput('_modelcheck', 'ERROR'); call symput('model'||trim(left(put(i,4.))), left(model)); call symput('itch'||trim(left(put(i,4.)" )), left(choices)); if _maxchoice"ADDCELL" 0.000001"  data _null_; n_QP=int( (&highrng-&lowrng)/&intv_theta +1); call symput('n_QP', trim(left(n_QP))); run; data _null_; array QP {&n_QP}; array prior {&n_QP}; do j=1 to &n_QP; QP[j]=&lowrng+(j-1)*&intv_theta; end; var=2*&p_std**2; total=0; do j=1"  to &n_QP; prior[j]=exp(-(QP[j]-&p_mean)**2/var); total+prior[j]; end; do j=1 to &n_QP; prior[j]=prior[j]/total; call symput('QP' || trim(left(j)), QP[j]); call symput('Prior' || trim(left(j)), prior[j]);" end; run; data _rawdata; set &data; array _it (*) &UsedItem; do i=1 to dim(_it); if _it[i]=&missing then _it[i]=.; * else _it[i]=_it[i]-&mincode+1; end; array lik {&n_QP}; array PostP {&n_QP}; do i=1 to &n_QP; _likeli=1;"( __J1&nitems1" &&_it&__J ne ." %c_icc(model=&&model&__J, _theta=symget("QP"||left(i)), _itno= &__J, _itsco= &&_it&__J); _likeli = _likeli * icc&__J;" ""  lik[i]=_likeli; p=1*symget("Prior"||left(i)); PostP[i]=lik[i]*p; end; sumPostP=sum(of PostP1-PostP&n_QP); do i=1 to &n_QP; PostP[i]=PostP[i]/sumPostP; end; loglikely_2=-2*log(sumPostP); run; proc sql; select sum(loglikely_2)" into :loglikely_2 from _rawdata; quit; proc means data=_rawdata; var PostP1-PostP&n_QP; output out=postP sum=postP1-PostP&n_QP; run; data QP_probs(keep=i QP Theta MargExpFreq Prior Posteri); set postP; array PostP {&n_QP}; sum=sum(of postP1-" PostP&n_QP); do i=1 to &n_QP; QP=1.*symget("QP"||left(i)); Theta=int(QP*100)/100; MargExpFreq=PostP[i]; Prior=1.*symget("Prior"||left(i)); Posteri=PostP[i]/sum; output; end; run; data jak_QP_probs; set QP_probs; run; proc means"  data=QP_probs VARDEF=WEIGHT; var QP; weight Posteri; output out=post_summary mean=post_mean std=post_std; run; proc sql; select post_mean into :post_mean from post_summary; select post_std into :post_std from post_summary; quit;" data _IRTTEST; length item $12; run; data _output2; run; data _IRTFreq; set QP_probs(keep=Theta MargExpFreq Posteri rename=(MargExpFreq=Count Posteri=Percent)); label theta='Quadrature point'; label Count='Pseudo Count'; label"H< Percent='Posterior Distribution'; percent=100*percent; run;"()__J1&nitems1"  proc means data=_rawdata; class &&_it&__J; var PostP1-PostP&n_QP; output out=_obs sum=QP1 - QP&n_QP; run; data _obs; set _obs; if &&_it&__J^=.; keep &&_it&__J QP1-QP&n_QP; run; data jak_obs&__j; set _obs; run; proc transpose data=_obs out="tran_obs prefix=Obs; var QP1-QP&n_QP; id &&_it&__J; run; data _IRTFreqj _IRTTESTj(keep=n_zero n_cells df adjust X2 G2 X2_adj G2_adj); set Tran_obs end=last; array Obs {&&itch&__J} Obs&mincode - Obs%eval(&&itch&__J+&mincode-1); array Pre {&"&itch&__J} Pre&mincode - Pre%eval(&&itch&__J+&mincode-1); array Std {&&itch&__J} Std&mincode - Std%eval(&&itch&__J+&mincode-1); MargExpFreq=sum(of Obs&mincode - Obs%eval(&&itch&__J+&mincode-1)); QP=1.*symget('QP'||left(_n_)); %c_icc(model=&"&model&__J, _theta=QP, _itno= &__J, _itsco= ALL); do i=1 to &&itch&__J; Pre[i]=MargExpFreq*icc_a&__J[i]; end; retain n_zero df X2 G2 use 0 ; if abs(QP)<&FitBound then do; use+1; do i=1 to &&itch&__J; if Obs[i]<0.00001 then do;"  Obs[i]=Obs[i]+&addcell; n_zero+1; end; Std[i]=.; if Pre[i]>&critcut and Obs[i]>0.00001 then do; df+1; G2+2*Obs[i] * log( Ob ||trim(left(put(i,4.)))||'_'||left(j), left(slopes(j))); call symput ('int'||trim(left(put(i,4.)))||'_'||left(j), left"(intercepts(j))); end; end; if upcase(trim(left(model))) = 'DI1P' then n_parm = 1; else if upcase(trim(left(model))) = 'DI2P' then n_parm = 2; else if upcase(trim(left(model))) = 'DI3P' then" n_parm = 3; else if upcase(trim(left(model))) = 'GRM' then n_parm = choices; else if upcase(trim(left(model))) = 'GPCM' then n_parm = choices; else if upcase(trim(left(model))) = 'PCM' then n_parm = choices-1;" else if upcase(trim(left(model))) = 'NOM' then n_parm = (choices-1)*2; else if upcase(trim(left(model))) = 'GRSM' then n_parm = 2 + &_mrpars; else if upcase(trim(left(model))) = 'RSM' then n_parm = 1 + &_mrpars;" call symput('n_parm'||trim(left(put(i,4.))), n_parm); end; end; if last then call symput('_maxchoice', trim(left(_maxchoice))); run;"&&_modelcheck = MISSING"M=Model type specified to be read from the Item Parameter file,"D4but model specifications are missing for some items."%This macro will stop."EXIT" ;""$&_modelcheck = ERROR"B2Wrong model specification for at least some items."WGUse the following model names: DI1P DI2P DI3P GRM GPCM PCM GRSM RSM NOM"%This macro will stop."EXIT" ;""PD proc sql noprint; select count(*) into :n_obs from &data; quit;"+%upcase(&testmethod)^= NONE"*%upcase(&testmethod)=THETA" %IRTFIT_theta"" %IRTFIT_SUM""%%upcase(&LD_test)=YES" %IRT_LocalDep"" *************************************************************************************** Final output ***************************************************************************************;" ods exclude none;"+%upcase(&testmethod)^= NONE":*"%trim(%left(%upcase(&outlib)))" ^= "NONE""  libname _irtfit "&outlib"; data _irtfit.&outcore._freq; set _IRTfreq; run; data _irtfit.&outcore._fit; length item_no 8 name $8 model $8 n_param 8; set _IRTTest; model = symget('model'"_S||left(item_no) ); n_param = symget('n_parm'||left(item_no) ); run;"" data work.&outcore._freq; set _IRTfreq; run; data work.&outcore._fit; length item_no 8 name $8 model $8 n_param 8; set _IRTTest; model = symget('model'||left(item_no) ); n_param = symget("3''n_parm'||left(item_no) ); run;""%%upcase(&LD_test)=YES":*"%trim(%left(%upcase(&outlib)))" ^= "NONE""OC data _irtfit.&outcore._LD; set _LD_Test; run;""L@ data work.&outcore._LD; set _LD_Test; run;""\L(%upcase(&outfmt)=RTF | %upcase(&outfmt)=PDF) AND "%upcase(&outlib)"^="NONE"" ods listing close; ods &outfmt file="&outlib\&outcore..&outfmt" style=journal; options orientation=landscape;"" footnote;"*%upcase(&testmethod)^=NONE" options nodate;"'%upcase(&output) = H s[i]/Pre[i] ); Std[" i]=(Obs[i]-Pre[i])/sqrt(Pre[i]); X2+Std[i]**2; end; end; end; output _IRTFreqj; if last then do; n_cells=use*&&itch&__J; adjust=n_cells / df; df=max(0.1, df-use); X2_adj=X2*" adjust; G2_adj=G2*adjust; output _IRTTESTj; end; run; data _output20(keep=QP_num theta stat resp freq prob); set _IRTFreqj end=last; array Obs {&&itch&__J} Obs&mincode - Obs" %eval(&&itch&__J+&mincode-1); array Pre {&&itch&__J} Pre&mincode - Pre%eval(&&itch&__J+&mincode-1); array Std {&&itch&__J} Std&mincode - Std%eval(&&itch&__J+&mincode-1); array _tot {&&itch&__J}; retain _tot1"-_tot&&itch&__J 0; length stat $8 ; theta=int(symget('QP' || left(_n_) )*100)/100; QP_num=_n_; total_obs=sum(of Obs&mincode - Obs%eval(&&itch&__J+&mincode-1)); total_Pre=sum(of Pre&mincode -" Pre%eval(&&itch&__J+&mincode-1)); do __i=1 to &&itch&__J; resp=__i+&mincode-1; _tot[__i]=_tot[__i]+Obs[__i]; stat='1Obs'; freq=Obs[__i]; prob=freq/total_obs; output; stat='2Pre';" freq=Pre[__i]; prob=freq/total_Pre; output; stat='3Std_Res'; freq=Std[__i]; prob=.; output; end; resp=9;stat='1Obs'; freq=MargExpFreq; output; if last then do;"  QP_num='999'; theta=999; stat='Sum '; do __i=1 to &&itch&__J; resp=__i+&mincode-1; freq=_tot[__i];output; end; resp=9" ; freq=sum(of _tot1-_tot&&itch&__J); output; end; run; data _output2; set _output2 _output20(in=in1); length item $12; if in1 then item="&&_it&__J"; run; data _IRTFreq; merge _IRTFreq _IRTFreqj"(keep=MargExpFreq"H#_ITCHNO&mincode%eval(&&itch&__J+&mincode-1)1"H< Obs&_itchno Pre&_itchno""J> rename=(MargExpFreq=&&_it&__J.._n"H'_ITCHNO&mincode%eval(&&itch&__J+&mincode-1)1" Obs&_itchno = &&_it&__J.._O_%eval(&_itchno-&mincode+1) Pre&_itchno = &&_it&__J.._E_%eval(&_itchno-&mincode+1)""  )); label &&_it&__J.._n=; run; data _IRTTEST; set _IRTTEST _IRTTESTj(in=inj); if inj=1 then do; item="&&_it&__J"; item_no=1*&__J; end; run;""<0 data _IRTTEST; set _IRTTEST; if item^=' '; run;"(R%upcase(&sampleTest)=YES"E5Resample based item fit test is running , please wait"SEED1" &seed"% data _simu_IRTTEST; run;"'I_IS1&N_rep1".Resampling &_is / &n_rep"?3 data _simu; do id=1 to &n_obs; r1=normal(&seed1);"(6__J1&nitems1" r2=ranuni(&seed1); %c_icc(model=&&model&__J, _theta=r1, _itno=&__J, _itsco= ALL); sum=0; kk=0; do while(sum",EXIT" ******************************************************************************; *; * control scale specification *; ******************************************************************************;"hX%upcase(%trim(%left(&scale))) ne TOTAL and %upcase(%trim(%left(&scale))) ne SUBTOTAL"EXIT"H8Scale must be specified as TOTAL or SUBTOTAL !!!!!!!!!?""_MAXCH" 2"eY data _null_; set _par end=last; retain match (0); retain maxsum (0); retain minsum (0);"' _J1&nitems1" if TRIM(upcase(name))= "%upcase(&&_it&_j)" then do; if choices > symget('_maxch') then call symput('_maxch', left(choices)); maxsum = maxsum + choices - 1; end;""t if last then do; call symput('maxsum', left(maxsum)); call symput('minsum', left(minsum)); end; run;"ITEM" ALL"+%trim(%upcase(&item)) = ALL"_FIRSTIT" 1"_LASTIT" &nitems""_FIRSTIT" &item"_LASTIT" &item" data _sumscal; set &data; array _it (*) &UsedItem; do i=1 to dim(_it); if _it[i]=&missing then _it[i]=.; end; _missing= nmiss(of &useditem); run;"5%%upcase(%trim(%left(&rescale))) = YES"  proc means data= _sumscal (where= ( _missing = 0 )) NOPRINT; var &useditem; output out=_minval min=&useditem; run; data _null_; set _minval; array _mini(*) &useditem; do i=1 to dim(_mini); call symput('_min'||trim(left(put(i,4.))), trim(left("put(_mini(i),4.)))); end; run; data _sumscal; set _sumscal; array rescore(*) &useditem; do i=1 to &nitems; if rescore(i) ne . then rescore(i)=rescore(i)-symget('_min'||left(i)); end; run;" " data _sumscal; set _sumscal; array rescore(*) &useditem; do i=1 to &nitems; if rescore(i) ne . then rescore(i)=rescore(i)-&mincode; end; run;"M_CHOICE" yes"'*_G1&nitems1" proc freq data= _sumscal NOPRINT; tables &&_it&_g /out= _frequen; run; data _NULL_; set _frequen (where= (&&_it&_g ne .)) end=last; choice = _N_; if last then call symput('testch', left(choice)); run;"#)&testch > &&itch&_g"M="Note: Item &&_it&_g has too many categories in the data set""M_CHOICE" no")""-&m_choice = no"EXIT"-"  data _sumscal; set _sumscal; scalesco = sum( of &useditem); if nmiss(of &useditem) > 0 then scalesco = .; run; proc freq data= _sumscal NOPRINT; tables scalesco /out= _frequen; run; data _fre_add; do scalesco = 0 to &maxsum; output; end;" run; data _frequen (drop= _sum); merge _frequen (where= (percent ne .)) _fre_add end=last; by scalesco; retain _sum (0); if count = . then count = 0; _sum = _sum + count; if last then call symput('great_n', trim(left(_sum)) ); run; data"  _frequen; set _frequen end= last; retain sum_n (0); sum_n = sum_n+count; if last then call symput('n_obs', trim(left(sum_n)) ); run; *******************************************************************; * * Latent distribution weights * ********" ***********************************************************; data _funct0; do theta= &lowrng to &highrng by &intv_sum; pos0 = exp(-(((theta-&p_mean)/&p_std)**2/2))/(2*3.14159265)**.5; output; end; run; ********************************************" **********************************; *; * Find sum of weights *; ******************************************************************************; data _funct0 (drop= _sumwght _nquadr); set _funct0 end=last; retain _sumwght (0); _sumwght = _sumwght +" pos0; _nquadr = _N_; if last then do; call symput('_sumwght', trim(left(_sumwght)) ); call symput('_nquadr', trim(left(_nquadr)) ); end; run; ******************************************************************************; *; * calculate item"} probabilities * loop over all items *; ******************************************************************************;"(< _I11&nitems1"  data _funct0; set _funct0 end=last; ******************************************************************************; *; * calculate item probabilities in each of the quadrature points *; ************************************************************"bV******************; %c_icc(model=&&model&_i1, _theta= theta, _itno= &_i1, _itsco=ALL)"+:  _C11&&itch&_i11"$ p&_i1.c&_c1 = icc&_c1;" " run;" " *******************************************************************; * * Calculate item score * sum score probabilities * Initiate long loop over each item * *******************************************************************;"4  ITEMNO&_firstit&_lastit1"OSVMAX" 0"OSPVAL" 1"  data _funct; set _funct0; run; *******************************************************************; * * Calculate probabilities for the subsum scale of * all items except the item in question * ********************************************"$***********************;"'Z _K1&nitems1"Y&itemno ne &_k"NSVMAX"* %eval(&osvmax+&&itch&_k-1)"NSPVAL" %eval(&nsvmax+1)"& data _funct; set _funct;"*N _C11&&itch&_k1"# icc&_c1 = p&_k.c&_c1;""  array pnewsum (&nspval) pns0 - pns&nsvmax; do i = 1 to &nspval; pnewsum(i) = 0; array poldsum(&ospval) pos0 - pos&osvmax; do j = 1 to &ospval; array icc_b (&&itch&_k) icc1-icc&&itch&_k; do k = 1 to &&itch&_k;" if (i-1) = (j-1) + (k-1) then pnewsum(i) = pnewsum(i) + poldsum(j)*icc_b(k); end; end; end; drop icc1-icc&&itch&_k pos0-pos&osvmax;"'S_M0&nsvmax1"& rename pns&_m = pos&_m;"" run;"OSVMAX" &nsvmax"OSPVAL" &nspval"Y" "  *******************************************************************; * * After calculating the probabilities for the subsum score, * we calculate the ICCs for the item in question * and the probabilities for the total sum score *"QE *******************************************************************;"NSVMAX". %eval(&osvmax+&&itch&itemno-1)"NSPVAL" %eval(&nsvmax+1)") data _funct; set _funct;".d _C11&&itch&itemno1"' icc&_c1 = p&itemno.c&_c1;"" *******************************************************************; * * Calculating probabilities when item*subtotal is reques ted * *******************************************************************;"8t(%upcase(%trim(%left(&scale))) = SUBTOTAL"!j&itemno= &_lastit" array pnewsum (&nspval) pns0 - pns&nsvmax; do i = 1 to &nspval; pnewsum(i) = 0; array poldsum(&ospval) pos0 - pos&osvmax; do j = 1 to &ospval; array icc_b (&&itch&itemno) icc1-icc&&itch&itemno; do k = 1 to &"&itch&itemno; if (i-1) = (j-1) + (k-1) then pnewsum(i) = pnewsum(i) + poldsum(j)*icc_b(k); end; end; end; run; data _funct; set _funct;"j"9- array psubsum (&ospval) pos0 - pos&osvmax;"-n _N1&&itch&itemno1" array nomi&_n (&ospval) n&_n._0 - n&_n._&osvmax; do i = 1 to &ospval; nomi&_n.(i) = psubsum(i)*icc&_n; end;"" run;"-s _O1&&itch&itemno1" proc means data= _funct noprint; var pos0 - pos&osvmax n&_o._0 - n&_o._&osvmax; output out= _sumn&_o sum= ; run; data _sumn&_o (keep= ex0 - ex&osvmax); set _sumn&_o; array expect (*) ex0 - ex&osvmax pos0 - pos"&osvmax n&_o._0 - n&_o._&osvmax; do i = 1 to &ospval; expect(i) = expect(i+2*&ospval)/ expect(i+&ospval); if expect(i) = . then expect(i) = 0; end; run;"""  *******************************************************************; * * Calculating probabilities when item*total is requested * *******************************************************************; array pnewsum (&nspval) pns0 - pns&nsvmax; do"  i = 1 to &nspval; pnewsum(i) = 0; array poldsum(&ospval) pos0 - pos&osvmax; do j = 1 to &ospval; array icc_b (&&itch&itemno) icc1-icc&&itch&itemno; do k = 1 to &&itch&itemno; if (i-1) = (j-1) + (k-1)" then pnewsum(i) = pnewsum(i) + poldsum(j)*icc_b(k); end; end; end; run; data _funct; set _funct; array psubsum (&ospval) pos0 - pos&osvmax;"-z _N1&&itch&itemno1" array nomi&_n (&nspval) n&_n._0 - n&_n._&nsvmax; do i = 1 to &nspval; do j = 1 to &ospval; if (i-1) = (j-1) + (&_n-1 ) then nomi&_n.(i) = psubsum(j)*icc&_n; end; end;"" run;"- _O1&&itch&itemno1" proc means data= _funct noprint; var pns0 - pns&nsvmax n&_o._0 - n&_o._&nsvmax; output out= _sumn&_o sum= ; run; data _sumn&_o (keep= ex0 - ex&nsvmax); set _sumn&_o; array expect (*) ex0 - ex&nsvmax pns0 - pns"&nsvmax n&_o._0 - n&_o._&nsvmax; do i = 1 to &nspval; expect(i) = expect(i+2*&nspval)/ expect(i+&nspval); if expect(i) = . then expect(i) = 0; end; run;"" data _comb; set"- _P1&&itch&itemno1" _sumn&_p"" ; run; proc transpose data= _comb prefix = i&itemno._pre name=scores out = _transp; run; data _transp; set _transp;"8(%upcase(%trim(%left(&scale))) = SUBTOTAL"! do i = 0 to &osvmax;""! do i = 0 to &maxsum;"aU if trim(left(upcase(scores))) = "EX"||left(i) then scalesco = i; end; drop i; run;"8(%upcase(%trim(%left(&scale))) = SUBTOTAL" data _sumscal2; set _sumscal; scalesco = scalesco - &&_it&itemno; run; proc freq data= _sumscal2; tables &&_it&itemno * scalesco /noprint out= _freq; run; proc freq data= _sumscal2; tables scalesco /noprint out= _freq2; run; ERRO""_S proc freq data= _sumscal; tables &&_it&itemno * scalesco /noprint out= _freq; run;"- _H1&&itch&itemno1"_HH" &_h - 1" data _ch&_h (keep= scalesco i&itemno._obs&_h); set _freq (where= (&&_it&itemno=&_hh and scalesco > .)); i&itemno._obs&_h = count; run;""." data _transp; merge _transp"8(%upcase(%trim(%left(&scale))) = SUBTOTAL"aU _freq2 (where= (scalesco ne .) drop= percent rename= (count = count&itemno))""- _H1&&itch&itemno1"# _ch&_h""vj end=last; by scalesco; run; data _frequen; merge _frequen _transp; by scalesco;"8(%upcase(%trim(%left(&scale))) = SUBTOTAL"OC if count&itemno = . and i&itemno._pre1 ne . then count&itemno = 0;""" count&itemno = count;"  array obs (&&itch&itemno) i&itemno._obs1- i&itemno._obs&&itch&itemno; do i = 1 to &&itch&itemno; if obs(i) = . then obs(i) = 0; end; array pre (*) i&itemno._pre1- i&itemno._pre&&itch&itemno i&itemno._e1- i&itemno._e&&itch&itemno"t; do i = 1 to &&itch&itemno; pre(i+&&itch&itemno)=pre(i); pre(i) = pre(i) * count&itemno; end; run;" "  data _IRTFreq; set _frequen; run; *******************************************************************; * * Calculation of fit statistics * Initiate file for chi-square values * **********************************************************" *********; data _chi_sq2; length item_no 8 item $8. n_cells X2 G2 8; run; *******************************************************************; * * Make a copy of outfile1 and reverse sort * **********************************************************"qe*********; data _collap0; set _IRTFreq; run; proc sort data= _collap0; by descending scalesco; run;"0 "_S&_firstit&_lastit1"  *******************************************************************; *; * fit statistics for each item based on the contingency * table with non-retangular collapsing *; ************************************************************"*******;"* #_RC1&&itch&_s1"  *******************************************************************************; *; * Prepare for collapsing of sparse score groups. First we identify * the center to be collapsed towards *; ******************************************************"*************************; proc means data= _IRTFreq noprint; var i&_s._pre&_rc; output out= _sumc sum= sum; run; data _null_; set _sumc; call symput("_sumc", sum); run;"CENTER" -1"  data _collap1(drop= _sum1b); set _collap0 (keep= scalesco count&_s i&_s._pre&_rc i&_s._obs&_rc i&_s._e&_rc where= (0 < i&_s._e&_rc < 1) ) ; retain _sum1b (0); _sum1b = _sum1b + i&_s._pre&_rc; if _sum1b < &min_pre then do; _add2b = 0; end;"  else do; _add2b = 1; _sum1b = 0; end; run; proc sort data= _collap1; by scalesco; run; *******************************************************************************; *; * Decide on the collapsing of sum scores with sparse categories *; **" *****************************************************************************; data _collap1 (keep= scalesco count&_s i&_s._pre&_rc i&_s._obs&_rc groupb _add1b _add2b _add3b); set _collap1; retain _sum(0); retain cum_1 (0); retain"  _sum1b (0); retain groupb (1); retain _add3b (0); _sum = _sum + i&_s._pre&_rc ; _sum1b = _sum1b + i&_s._pre&_rc ; if _sum1b < &min_pre then do; ERRO _add1b = 0; end; else do; _add1b = 1; _sum1b = 0; end; cum = (_sum < (&_sumc)/2); if cum = 0 and" cum_1 = 0 then _add3b = _add2b; cum_1 = cum; groupb = groupb + _add3b; if cum = 1 then _add3b = _add1b; run; ******************************************************************************; *; * calculate max, min, and n * for each"  score group *; ******************************************************************************; proc means data= _collap1 NOPRINT; var i&_s._pre&_rc i&_s._obs&_rc count&_s; by groupb; output out= _groups2b sum= ; run; **************************"****************************************************; *; * Pearson test - calculate chi-square contributions *; ******************************************************************************; data _null_ ; set _groups2b end=last; cat_nr = &_rc;" retain X2 (0); retain G2 (0); group = _n_; X2 = X2 + (i&_s._pre&_rc - i&_s._obs&_rc)**2 / i&_s._pre&_rc; G2 = G2 + i&_s._obs&_rc * log((i&_s._obs&_rc + 10**-60) / i&_s._pre&_rc); if last then do; call symput("X2_&_s.c&_rc", X2); call symput("PD"G2_&_s.c&_rc", G2); call symput("n_cells_&_rc", group); end; run;"#"  ******************************************************************************; *; * calculate test statistics for item test *; ******************************************************************************; data _chi2; length item_no"F: 8 item $8; item_no = &_s; item = "&&_it&_s"; n_cells = 0"+ $_RC11&&itch&_s1"( + &&n_cells_&_rc1"$"." ; X2 = 0"+ %_RC21&&itch&_s1"( + &&X2_&_s.c&_rc2"%"3' ; G2 = 2 * (0"+ &_RC21&&itch&_s1"( + &&G2_&_s.c&_rc2"&" ) ; run; proc append base = _chi_sq2 new = _chi2 (keep= item_no item n_cells X2 G2); run;""" data _irttest(drop=choices); set _chi_sq2 (where= (n_cells ne .)); choices = symget('itch'||trim(left(put(item_no,4.))) );"8(%upcase(%trim(%left(&scale))) = SUBTOTAL"8, df = round(n_cells * (choices-1) / choices)"3#%upcase(%trim(%left(&model))) = PCM"F: - (choices-1);""B6 - choices;""H< df = round(n_cells * (choices-1) / choices) - (choices - 2)"3#%upcase(%trim(%left(&model))) = PCM"VJ - (choices-1);""RF - choices;" if df > 0 then Prob_X2 = 1 - probchi(X2,df); else Prob_X2 = .; if df > 0 then Prob_G2 = 1 - probchi(G2,df); else Prob_G2 = .; rename item=name; run; data _IRTFreq; set _IRTFreq( rename=("0 -_S&_firstit&_lastit1"2& count&_s=&&_it&_s.._n"* ._RC1&&itch&_s1"pd i&_s._obs&_rc = &&_it&_s.._O_&_rc i&_s._pre&_rc = &&_it&_s.._E_&_rc"."-" )) ; drop"0 /_S&_firstit&_lastit1"* 0_RC1&&itch&_s1"  i&_s._e&_rc"0"/" sum_n scores;"0 1_S&_firstit&_lastit1"% label &&_it&_s.._n=;"1"  run; ******************************************************************************; *; *   delete temporary help data sets *; ******************************************************************************; proc datasets nodetails nolist; delete" _add _chi _chi2 _chi4 _chi_sq1 _chi_sq2 _chi_sq4 _collap _collap0 _collap1 _comb _freq _freq2 _frequen _fre_add _funct _funct0" _groups _groups0 _groups2 _groups2b _median _minval _pare _paro _predict _pred_obs _sumc _scollap1 _sgfrqsum _sgroups0 _sgroups2 _sumscal"H< _sumscal2 _trans _transp _tsums"(2_WW1&_maxch1"% _ch&_ww _sumn&_ww"2"'3_S1&nitems1" _bin&_s"3"  ; run; quit;"#,0 4  4`x0 H ` t <h(<Hl0X 8Pdlx,Lx8 h !!H!P",#4#H#T$`%$&T&<'D'X''(l)t)))))x**** +p++,, -<-P-h--.4.l.../8/@///@0T0x012 23$444556 77789:(;4<<=H>P?T@@@AB,BTB\BBBBBCHCpCxCDDDD E@EEEEE&critcut and Obs[i]>0.00001 then do; df+1; G2+2*Obs[i] * log( Obs[i]/Pre[i] ); Std[i]=(Obs[i]-Pre[i])/sqrt(Pre[i]); X2+Std[i]**2;" end; end; end; if last then do; n_cells=use*&&itch&__J; adjust=n_cells / df; df=max(0.1, df-use); X2=X2*adjust; G2=G2*adjust; output _IRTTESTj; end; run;" data _simu_IRTTEST; set _simu_IRTTEST _IRTTESTj(in=in1); if in1 then item_no=1.*&__J; run;" "" proc means data=_simu_IRTTEST; var X2 G2; class item_no; output out=_IRTTEST_sum mean=mean_X2 mean_G2 var=var_X2 var_G2; run;":M*"%trim(%left(%upcase(&outlib)))" ^= "NONE"" data _irtfit.&outcore._RESAMP; set _simu_IRTTEST (where= (item_no ne .)); run; proc sort data= _irtfit.&outcore._RESAMP; by item_no; run;"N" data work.&outcore._RESAMP; set _simu_IRTTEST (where= (item_no ne .)); run; proc sort data= work.&outcore._RESAMP; by item_no; run;" data _IRTTEST_sum; set _IRTTEST_sum; if item_no^=.; run; data _IRTTEST; merge _IRTTEST(rename=(X2=X2_0 G2=G2_0)) _IRTTEST_sum; by item_no; score_X=var_X2/mean_X2/2; df_X2_NA=mean_X2/score_X;" df_X2=max(0.1, df_X2_NA-symget('n_parm' || trim(left(item_no))) ); X2=X2_0/score_X; Prob_X2_NA=1-probchi(X2, df_X2_NA); Prob_X2=1-probchi(X2, df_X2); score_G=var_G2/mean_G2/2; df_G2_NA=mean_G2/score_G; df_G2=max(0.1," df_G2_NA-symget('n_parm' || trim(left(item_no))) ); G2=G2_0/score_G; Prob_G2_NA=1-probchi(G2, df_G2_NA); P ERRO`rob_G2=1-probchi(G2, df_G2); run;"S" data _IRTTEST; set _IRTTEST; df=max(0.1, df-symget('n_parm' || trim(left(item_no))) ); Prob_X2=1-probchi(X2, df); Prob_G2=1-probchi(G2, df); run;"H< data _IRTTEST; set _IRTTEST; keep"(W%upcase(&sampleTest)=YES" item_no item n_zero n_cells G2_0 G2 df_G2 Prob_G2 df_G2_NA Prob_G2_NA X2_0 X2 df_X2 Prob_X2 df_X2_NA Prob_X2_NA"X"WK item_no item n_zero n_cells adjust df G2 X2"  ; rename item=name; run; proc datasets; delete PostP Post_summary QP_probs Tran_obs _obs _seed _IRTTESTj _sum _IRTFreqj _output2 _output20 _simu _simu_IRTTEST _IRTTEST_sum _rawdata __parm ; run;"% quit; ods exclude none;"p#[0<HPx<PXdlx   $0<HPTT`l$p|D\t4\d<d8 L T T!!!"#$%&'(((|))h*|*(+,,0---|...// 0,1T1 ERRO"t IRT_LOCALDEPC9.1  D<8>",EXIT" data _sumscal; set &data; array _it (*) &UsedItem; do i=1 to dim(_it); if _it[i]=&missing then _it[i]=.; end; _missing= nmiss(of &useditem); run;"5%%upcase(%trim(%left(&rescale))) = YES"  proc means data= _sumscal (where= ( _missing = 0 )) NOPRINT; var &UsedItem; output out=_minval min=&UsedItem; run; data _null_; set _minval; array _mini(*) &UsedItem; do i=1 to dim(_mini); call symput('_min'||trim(left(put(i,4.))), trim(left("put(_mini(i),4.)))); end; run; data _sumscal; set _sumscal; array rescore(*) &UsedItem; do i=1 to &nitems; if rescore(i) ne . then rescore(i)=rescore(i)-symget('_min'||left(i)); end; run;"" data _sumscal; set _sumscal; array rescore(*) &useditem; do i=1 to &nitems; if rescore(i) ne . then rescore(i)=rescore(i)-&mincode; end; run;"M_CHOICE" yes"'_G1&nitems1" proc freq data= _sumscal NOPRINT; tables &&_it&_g /out= _frequen; run; data _NULL_; set _frequen (where= (&&_it&_g ne .)) end=last; choice = _N_; if last then call symput('testch', left(choice)); run;"#&testch > &&itch&_g"M="Note: Item &&_it&_g has too many categories in the data set""M_CHOICE" no"""&m_choice = no"EXIT"" *******************************************************************; * * Latent distribution weights * *******************************************************************; data _funct0; do theta= &lowrng to &highrng by &intv_sum; pos0 ="  exp(-(((theta-&p_mean)/&p_std)**2/2))/(2*3.14159265)**.5; output; end; run; ******************************************************************************; *; * Find sum of weights *; ************************************************************" ******************; data _funct0 (drop= _sumwght _nquadr); set _funct0 end=last; retain _sumwght (0); _sumwght = _sumwght + pos0; _nquadr = _N_; if last then do; call symput('_sumwght', trim(left(_sumwght)) ); call symput('_nquadr', trim(left(_nquadr))" ); end; run; ******************************************************************************; *; * calculate item probabilities * loop over all items *; ******************************************************************************;"(!_I11&nitems1"  data _funct0; set _funct0 end=last; ******************************************************************************; *; * calculate item probabilities in each of the quadrature points *; ************************************************************"bV******************; %c_icc(model=&&model&_i1, _theta= theta, _itno= &_i1, _itsco=ALL)"+ _C11&&itch&_i11"$ p&_i1.c&_c1 = icc&_c1;"" run;"" ******************************************************************************; *; * test for local dependence *; ******************************************************************************; data _funct; set _funct0;"(-_I12&nitems1"+, _C11&&itch&_i11" ******************************************************************************; *; * loop over lower item triangle *; ******************************************************************************;"0+ _I21%eval(&_i1 - 1)1"+*  _C21&&itch&_i21"  *********************** ERRO*******************************************************; *; * calculate expected proportions in all item*item cells for all * pairwise item combinations *; **************************************************************"g[****************; fi&_i1.c&_c1.i&_i2.c&_c2 = p&_i1.c&_c1 * p&_i2.c&_c2 * pos0 / &_sumwght;" " """=1 run; proc means data= _funct noprint; var"(7 _I11&nitems1"+6  _C11&&itch&_i11"05 _I21%eval(&_i1 - 1)1"+4 _C21&&itch&_i21"& fi&_i1.c&_c1.i&_i2.c&_c2"" " " " ; output out=_freq sum= ; run; proc transpose data= _freq (drop= _type_ _freq_) out= _trans; run; data _trans; set _trans (rename= (col1 = freq)); length name1 name2 $20 resp1 resp2 8;"(A_I11&nitems1"+@ _C11&&itch&_i11"0?_I21%eval(&_i1 - 1)1"+> _C21&&itch&_i21" if trim(left(_name_)) = "fi&_i1.c&_c1.i&_i2.c&_c2" then do; name1 = "&&_it&_i1"; name2 = "&&_it&_i2"; resp1 = &_c1-1; resp2 = &_c2-1; end;""""" run; data _ld_test; length Name1 Name2 $20 item_no1 item_no2 pred_corr obs_corr res_corr chisq gsq df p_chisq p_gsq 8 warning $60; run; ******************************************************************************; *; * loop over lover" triange item pairs to compare the observed and * expected bi-item frequency distribution *; ******************************************************************************;"(_I12&nitems1"0_I21%eval(&_i1 - 1)1"N_OBS" 0"  proc freq data= _sumscal (where= (&&_it&_i1 ne . and &&_it&_i2 ne .)) noprint; tables &&_it&_i1 * &&_it&_i2 /plcorr out= _observ sparse; output out= _paro plcorr; run; data _null_; set _observ end=last; retain _cumfreq(0); if count ne . then _cumfreq ="]Q _cumfreq + count; if last then call symput('n_obs', trim(left(_cumfreq)) ); run;" &n_obs ne 0"  data _predict (drop= name1 name2); set _trans (where= (trim(name1) = "&&_it&_i1" and trim(name2) = "&&_it&_i2") rename= (resp1 = &&_it&_i1 resp2= &&_it&_i2) ); freq = freq * &n_obs; run; proc freq data= _predict noprint; weight freq; tables"  &&_it&_i1 * &&_it&_i2 /plcorr; output out= _pare plcorr; run; ***************************************************************************; * The next long part evaluates collapsing and calculates X**2 and G**2 ****************************************"K?***********************************; *options mprint symbolgen;" _ICOLLAPS" 0"_MAXIT1"  &&itch&_i1"_MAXIT2"  &&itch&_i2"_WARNING" 0" data _pred_obs; merge _predict _observ (rename= (count = obs) drop= percent) end=last; by &&_it&_i1 &&_it&_i2; retain _chisq (0) _gsq (0) _min (&n_obs) _min1 (0) _min2 (0)")Y_C11&_maxit11"* &&_it&_i1.._m&_c1 (0)"")\_C21&_maxit21"* &&_it&_i2.._m&_c2 (0)""  ; _chisq = _chisq + (freq - obs)**2 / freq; if obs = 0 then obs = 1/10**9; _gsq = _gsq + 2*obs*log(obs/freq); array _m1 (*) &&_it&_i1.._m1-&&_it&_i1.._m&_maxit1; array _m2 (*) &&_it&_i2.._m1-&&_it&_i2.._m&_maxit2; if freq"  < _min then do; _min = freq; _min1 = &&_it&_i1; _min2 = &&_it&_i 2; end; do _c1 = 1 to &_maxit1; if &&_it&_i1 = _c1-1 then _m1(_c1) = _m1(_c1) + freq; end; do _c2 = 1 to &_maxit2; if &&_it&_i2 = _c2-1 then _m2(_c2) = _m2(_c2)"  + freq; end; if last then do; if _min < &min_pre then do; **** Decide what item to collaps ****; if (_m1(_min1+1) < _m2(_min2+1) or &_maxit2 = 2) and &_maxit1 > 2 then do; call symput('_icollaps', '1'); **** Decide what values to collaps ****;" if _min1 = 0 then call symput('_collapsv', trim(left(_min1)) ); else if _min1 = &_maxit1-1 then call symput('_collapsv', trim(left(_min1-1)) ); else if _m1(_min1) < _m1(_min1+2) then call symput('_collapsv', trim(left(_min1-1)) ); else call symput(" '_collapsv', trim(left(_min1)) ); end; else if &_maxit2 > 2 then do; call symput('_icollaps', '2'); **** Decide what values to collaps ****; if _min2 = 0 then call symput('_collapsv', trim(left(_min2)) ); else if _min2 = &_maxit2-1 then call symput("'_collapsv', trim(left(_min2-1)) ); else if _m2(_min2) < _m2(_min2+2) then call symput('_collapsv', trim(left(_min2-1)) ); else call symput('_collapsv', trim(left(_min2)) ); end; else do; call symput('_warning', '1'); call symput('_cchisq', trim(left(" _chisq)) ); call symput('_cgsq', trim(left(_gsq)) ); df = (&_maxit1 - 1) * (&_maxit2 - 1); if df > 0 then do; p_chisq = 1 - probchi(_chisq,df); p_g = 1 - probchi(_gsq,df); end; else do; p_chisq = .; p_g = .; end; call symput('_cdf', trim(left(df))"  ); call symput('_p_cchisq', trim(left(p_chisq)) ); call symput('_p_cg', trim(left(p_g)) ); end; end; else do; call symput('_cchisq', trim(left(_chisq)) ); call symput('_cgsq', trim(left(_gsq)) ); df = (&_maxit1 - 1) * (&_maxit2 - 1); if df > 0 then do;" p_chisq = 1 - probchi(_chisq,df); p_g = 1 - probchi(_gsq,df); end; else do; p_chisq = .; p_g = .; end; call symput('_cdf', trim(left(df)) ); call symput('_p_cchisq', trim(left(p_chisq)) ); call symput('_p_cg', trim(left(p_g)) ); end; end; run;"@0&_icollaps > 0 and &_MAXIT1 > 1 and &_MAXIT2 > 1" _MAXIT&_ICOLLAPS"- %eval(&&_maxit&_icollaps - 1)" data _pred_obs; set _pred_obs; if &&&&_it&&_i&_icollaps > &_collapsv then &&&&_it&&_i&_icollaps = &&&&_it&&_i&_icollaps - 1; run; proc means data= _pred_obs noprint; class &&_it&_i1 &&_it&_i2; var freq obs; output out= _pred_obs_c sum= ; run;" _ICOLLAPS" 0"{ data _pred_obs; set _pred_obs_c (where=(_type_=3)) end=last; retain _chisq (0) _gsq (0) _min (&n_obs) _min1 (0) _min2 (0)")o_C11&_maxit11"* &&_it&_i1.._m&_c1 (0)"")r_C21&_maxit21"* &&_it&_i2.._m&_c2 (0)""  ; if obs = 0 then obs = 1/10**9; _chisq = _chisq + (freq - obs)**2 / freq; _gsq = _gsq + 2*obs*log(obs/freq); array _m1 (*) &&_it&_i1.._m1-&&_it&_i1.._m&_maxit1; array _m2 (*) &&_it&_i2.._m1-&&_it&_i2.._m&_maxit2; if freq <"  _min then do; _min = freq; _min1 = &&_it&_i1; _min2 = &&_it&_i2; end; do _c1 = 1 to &_maxit1; if &&_it&_i1 = _c1-1 then _m1(_c1) = _m1(_c1) + freq; end; do _c2 = 1 to &_maxit2; if &&_it&_i2 = _c2-1 then _m2(_c2) = _m2(_c2) +" freq; end; if last then do; if _min < &min_pre then do; **** Decide what item to collaps ****; if (_m1(_min1+1) < _m2(_min2+1) or &_maxit2 = 2) and &_maxit1 > 2 then do; call symput('_icollaps', '1');" **** Decide what values to collaps ****; if _min1 = 0 then call symput('_collapsv', trim(left(_min1)) ); else if _min1 = &_maxit1-1 then call symput('_collapsv', trim(left(_min1-1)) );" else if _m1(_min1) < _m1(_min1+2) then call symput('_collapsv', trim(l ERROeft(_min1-1)) ); else call symput('_collapsv', trim(left(_min1)) ); end; else if &_maxit2 > 2 then do; call" symput('_icollaps', '2'); **** Decide what values to collaps ****; if _min2 = 0 then call symput('_collapsv', trim(left(_min2)) ); else if _min2 = &_maxit2-1 then call symput('_collapsv', trim(left("_min2-1)) ); else if _m2(_min2) < _m2(_min2+2) then call symput('_collapsv', trim(left(_min2-1)) ); else call symput('_collapsv', trim(left(_min2)) ); end; else do; call symput("'_warning', '1'); call symput('_cchisq', trim(left(_chisq)) ); call symput('_cgsq', trim(left(_gsq)) ); df = (&_maxit1 - 1) * (&_maxit2 - 1); if df > 0 then do;" p_chisq = 1 - probchi(_chisq,df); p_g = 1 - probchi(_gsq,df); end; else do; p_chisq = .; p_g = .;" end; call symput('_cdf', trim(left(df)) ); call symput('_p_cchisq', trim(left(p_chisq)) ); call symput('_p_cg', trim(left(p_g)) ); end; end; else do;"  call symput('_cchisq', trim(left(_chisq)) ); call symput('_cgsq', trim(left(_gsq)) ); df = (&_maxit1 - 1) * (&_maxit2 - 1); if df > 0 then do; p_chisq = 1 - probchi(_chisq,df); p_g = 1 -" probchi(_gsq,df); end; else do; p_chisq = .; p_g = .; end; call symput('_cdf', trim(left(df)) ); call symput('_p_cchisq', trim(left(p_chisq)) ); call"F: symput('_p_cg', trim(left(p_g)) ); end; end; run;"" ********************************************************************; * Combine all test statistics ********************************************************************; data _add; Length Name1 Name2 $20 item_no1 item_no2"  pred_corr obs_corr res_corr chisq gsq df p_chisq p_gsq 8 warning $60; merge _pare (drop= E_PLCORR rename= (_PLCORR_ = pred_corr) ) _paro (drop= E_PLCORR rename= (_PLCORR_ = obs_corr) ); Name1 = "%upcase(&&_it&_i1)"; item_no1=&_i1;"  Name2 = "%upcase(&&_it&_i2)"; item_no2=&_i2; res_corr = (obs_corr - pred_corr); chisq = &_cchisq; gsq = &_cgsq; df = &_cdf; p_chisq = &_p_cchisq; p_gsq = &_p_cg; if &_warning=1 then warning="Collapsing did not achieve minimum predicted > &min_pre"; run" ;"" data _add; Length Name1 Name2 $20 item_no1 item_no2 pred_corr obs_corr res_corr chisq gsq df p_chisq p_gsq 8 warning $60; Name1 = "%upcase(&&_it&_i1)"; item_no1=&_i1; Name2 = "%upcase(&&_it&_i2)"; item_no2=&_i2; run;" proc append base= _ld_test data= _add FORCE; run; proc datasets nodetails nolist; delete _paro; run; quit;""" data _ld_test; set _ld_test (where= (trim(name1) ne ' ')); rename chisq=X2 gsq=G2 p_chisq=Prob_X2 p_gsq=Prob_G2 ; run; ******************************************************************************; *; * delete temporary help data"  sets *; ******************************************************************************; proc datasets nodetails nolist; delete _add _freq _frequen _funct _funct0 _observ _pare _predict _pred_obs"QE _pred_obs_c _sumscal _trans ; run; quit;"8#,@Xl  (  H $T T|,4<DL4\hXt <TpX$0<D P!X"d#p$x%%%&'$'8'''( (L(x(()*+,-./0123444578 84849999:;@<"t IRTFIT_GRAPHC9.1  g0>"8DATA_IRTFreq"0PLOTITEM"1MIN_PRE5"3TICK_TXTYES",EXITe" *options nomprint nomlogic nosymbolgen nonotes nostimer; *options mprint; * graphics template to graph up to 6 response categories at one time; goptions reset=global display colors=(black) ROTATE=LANDSCAPE ; goptions reset=(axis, legend, pattern,"  symbol, title, footnote) hpos=0 vpos=0 htext= ftext= ctext= htitle= 1.5 target= gaccess= gsfmode= ; goptions device=WIN ctext=blue graphrc; proc greplay nofs tc=sasuser.templt; tdef graf2by3 4 / llx = 2" lly = 4 ulx = 2 uly = 49 urx = 33 ury = 49 lrx = 33 lry = 4 1 / llx = 2 lly = 50 ulx = 2 uly = 94" urx = 33 ury = 94 lrx = 33 lry = 50 5 / llx = 34 lly = 4 ulx = 34 uly = 49 urx = 65 ury = 49" lrx = 65 lry = 4 2 / llx = 34 lly = 50 ulx = 34 uly = 94 urx = 65 ury = 94 lrx = 65 lry = 50" 6 / llx = 66 lly = 4 ulx = 66 uly = 49 urx = 97 ury = 49 lrx = 97 lry = 4 3 / llx = 66 lly = 50" ulx = 66 uly = 94 urx = 97 ury = 94 lrx = 97 lry = 50 7 / llx=2 lly=2 ulx=2 uly=99"  urx=99 ury=99 lrx=99 lry=2 ; run; quit; proc greplay nofs igout=work.greps; delete _all_; run; proc greplay nofs igout=work.gseg; delete _all_; run; **********" ****************************************************************; *; * Evaluate whether scale=theta, scale= SUMscore *; **************************************************************************; data __temp; set &data end=last; retain n_p 0 n_s 0;"  if theta^=. then n_p+1; if scalesco^=. then n_s+1; if scalesco=. then scalesco=theta; if last then do; if n_p> 0 then call symput('_scale', 'Theta'); if n_s> 0 then call symput('_scale', 'SumScore'); end; run; **********************************"****************************************; *; * Set parameters for plotting *; **************************************************************************; **************************************************************************; *; * Read item"  names *; **************************************************************************; data _null_; array _y (*) &plotitem; length name $12; do i=1 to dim(_y); call vname(_y{i}, name); call symput('_it'||trim(left(put(i,4.))), trim(left(upcase("YMname))) ); end; p=dim(_y); call symput('nplot', trim(left(put(p,4.)))); run;"MAXITCH" 2"*dITEMNO1&nplot1"RF data __tempj; set __temp end=last; count&itemno = &&_it&itemno.._n ;""__J161"l` i&itemno._Obs&__j = &&_it&itemno.._O_&__j ; i&itemno._pre&__j = &&_it&itemno.._E_&__j ;"" ; array _pre (* ERRO) i&itemno._pre1 - i&itemno._pre6; array _e (*) i&itemno._e1 - i&itemno._e6; array _obs (*) i&itemno._obs1 - i&itemno._obs6; array _O (*) i&itemno._O1 - i&itemno._O6; array _n (*) _n1 - _n6; retain _n1 _n2 _n3 _n4 _n5 _n6 0; do ii=1 to 6;"  _e[ii]=.; if _pre[ii]^=. then do; _n[ii]+1; if count&itemno = 0 then _e[ii] = 0; else _e[ii]=_pre[ii] / count&itemno; if count&itemno = 0 then _O[ii] = 0; else _O[ii]=_obs[ii] / count&itemno; end; end; if last then do; itch=0; do ii="oc1 to 6; if _n[ii]>0 then itch=ii; end; call symput('itch', trim(left(itch))); end; run;"!&itch>&&maxitch"MAXITCH" &itch"!"  data _plot0; set __tempj (where= (count&itemno ne .)) end=last; nummer = _N_; if nummer = 1 then call symput('lowrngs', left(scalesco)); else if last then do; call symput('highrngs', left(scalesco)); call symput('maxgroup'," left(nummer)); end; call symput('_sgr'||left(nummer), left(trim(count)) ); run; goptions reset=global nodisplay; proc greplay nofs igout=work.gseg; delete _all_; run;")&_scale = Theta"%(_C1&itch1"  proc gplot data=_plot0; plot ( i&itemno._E&_c i&itemno._O&_c) * Theta / overlay haxis=axis1 vaxis=axis2 ; title h=3 f=swiss "Item Score &_c" ; symbol1 c=black i=J l=1 v=POINT; symbol2 c=black i="none v=STAR; axis1 color= black width=2.0 label=(h=3.5 f=swiss 'Theta') value=(h=3); axis2 color=black width=2.0 label=NONE order= (0 to 1 by 0.2) value=(h=3); run; title ' ' ;"")""]&_scale = SumScore" *******************************************************************************; *; * This part prepares the plotting of observed-expected for each trace line *; *******************************************************************************;"%\_C1&itch1"  *******************************************************************************; *; * Prepare for collapsing af sparse score groups. First we identify * the center to be collapsed towards for each trace line *; ********************************"***********************************************; proc means data= _plot0 NOPRINT; var i&itemno._pre&_c; output out= _sumc sum= sum; run; data _null_; set _sumc; call symput('_sumc', sum); run;"CENTER" -1" data _plot (drop= _sum1 _sum2); set _plot0 (keep= scalesco count&itemno i&itemno._pre&_c i&itemno._obs&_c i&itemno._e&_c where= (0 < i&itemno._pre&_c < count&itemno) ) end=last; i&itemno._pre0 = count&itemno - i"&itemno._pre&_c; retain _sum1 (0); retain _sum2 (0); retain _cum (0); _sum1 = _sum1 + i&itemno._pre&_c; _sum2 = _sum2 + i&itemno._pre0; _cum = _cum + i&itemno._pre&_c; if _cum < &_sumc/2 then call symput('center', scalesco); if _sum1 < &min_pre or" _sum2 < &min_pre then do; _add1 = 0; end; else do; _add1 = 1; _sum1 = 0; _sum2 = 0; end; run; proc sort data= _plot; by descending scalesco; run; data _plot (drop= _sum1 _sum2); set _plot; retain _sum1 (0); retain _sum2 (0); _sum1 ="  _sum1 + i&itemno._pre&_c ; _sum2 = _sum2 + i&itemno._pre0; if _sum1 < &min_pre or _sum2 < &min_pre then do; _add2 = 0; end; else do; _add2 = 1; _sum1 = 0; _sum2 = 0; end; run; proc sort data= _plot; by scalesco; run; **********************" *********************************************************; *; * Decide on the collapsing of sum scores with sparse categories *; *******************************************************************************; data _plot (keep= scalesco count&itemno" i&itemno._pre&_c i&itemno._obs&_c group _add1 _add2 _add3); set _plot; retain group (1); retain _add3 (0); retain cum_1 (0); cum = (scalesco le ¢er); if cum = 0 and cum_1 = 0 then _add3 = _add2; cum_1 = cum; group = group + _add3; if cum = 1" then _add3 = _add1; run; * Save the files with collapsing instructions to check the collapsing logic; * Disabled; * data _chk&itemno._&_c; * set _plot; * run; proc univariate data= _plot NOPRINT; var scalesco; by group; output out= _groups0" min= minval max= maxval; run; proc univariate data= _plot NOPRINT; var scalesco; by group; freq count&itemno; output out= _groups1 n= count&itemno ; run; proc means data= _plot NOPRINT; var i&itemno._pre&_c i&itemno._obs&_c; by group;"  output out= _groups2 sum= ; run; data _groups; merge _groups0 _groups1 _groups2 end=last; by group; _small = min(i&itemno._obs&_c, (count&itemno - i&itemno._obs&_c)); if _small = 0 then _small = .5; i&itemno._pre&_c = i&itemno._pre&_c / count" &itemno; i&itemno._obs&_c = i&itemno._obs&_c / count&itemno; ******************************************************************************; *; * Calculating confidence interval for the predicted proportions *; ************************************" ******************************************; _M = log( i&itemno._pre&_c / (1 - i&itemno._pre&_c) ); _S = sqrt( 1/(count&itemno*i&itemno._pre&_c) + 1/(count&itemno*(1-i&itemno._pre&_c) ) ); _low = _M - 1.96*_S; _high = _M + 1.96*_S; i&itemno._low&_c = exp" (_low) / (1+exp(_low)); i&itemno._high&_c = exp(_high) / (1+exp(_high)); drop _M _S _low _high; label i&itemno._pre&_c= "Item Score &_c"; label i&itemno._sre&_c= "Item Score &_c"; **********************************************************************"********; *; * Output important parameters for plotting *; ******************************************************************************; call symput('_sgr'||left(group), '(n='||trim(left(count&itemno))||')' ); if _freq_ = 1 then call symput("'_bgr'||left(group), 's='||trim(left(minval))); else call symput('_bgr'||left(group), 's='||trim(left(minval))||'-'||trim(left(maxval)) ); if last then call symput('maxgroup', left(group) ); run;"B&maxgroup < 15"HIGHT" 3"L"F&maxgroup < 20"HIGHT" 2.5"L"J&maxgroup < 40"HIGHT" 2"L"HIGHT" 1.4" proc gplot data=_groups; plot (i&itemno._pre&_c i&itemno._low&_c i&itemno._high&_c i&itemno._obs&_c) * GROUP / overlay haxis=axis1 vaxis=axis2 ; title h=3.5 f=swiss "Item Score &_c ";" symbol1 c=black i=J l=1 v=POINT ; symbol2 c=black i=J l=34 v=POINT ; symbol3 c=black i=J l=34 v=POINT ; symbol4 c=black i=none v=star ;"6U&%upcase(%trim(%left(&tick_txt))) = YES"UI axis1 color=black width=2.0 order= (1 to &maxgroup) value= (")S _B1&maxgroup1"NB h= &hight angle= 90 tick= &_b justify= c "&&_bgr&_b"""?3 ) label= (h=3.5 f=swiss 'Sum Score Group') ;"V"_S axis1 color= black width=2.0 label=(h=3.5 f=swiss 'Sum Score Group') ;"UI axis2 color=black width=2.0 order= (0 to 1 by 0.2) value= (""Z _B1101"# h= &hight" "WK ) label= NONE; axis3 color=black width=2.0 ; run; title ' ' ;""]" ERRO data _null_; rc=gset('catalog','work','gseg'); rc=ginit(); call gask('numgraph', count, rc); call symput('ncat',count); rc=gterm(); run; proc gslide name="slide_&itemno"; title1 h=2 f=swiss" "Expected and observed proportions for &&_it&itemno: &_scale"; run; proc greplay nofs igout=work.gseg gout=work.greps tc=sasuser.templt; template graf2by3; treplay"&b __K1&itch1" &__k : &__k" "<0 7 : slide_&itemno ; run; quit;"" goptions device=WIN display; proc greplay nofs igout=work.greps; replay _all_; run; quit; goptions reset=all; title1 ' ' ;"# options notes stimer;"#g8h  ( 4 <`\|(408@HT`hp x!"#$%&'''''((0(D(d(|((((()**,+X++++,d,,,- -d-l--|.8/`/|////00UGE"'"_I1&nitems1"8, proc print data=_IRTFreq noobs; var",%upcase(&testmethod) = THETA"  theta count"" scalesco") %_C1&&itch&_i1"." IT&_i._O_&_c IT&_i._E_&_c"%"/# ;",%upcase(&testmethod) = THETA"bV title "Expected and pseudo-observed item response frequencies for &&_it&_i ";""[O title "Expected and observed item response frequencies for &&_it&_i ";" run;""""*%upcase(&testmethod)=THETA"(%upcase(&SampleTest)=YES" proc print data=_IRTTest noobs; var item_no name G2 df_G2 Prob_G2 X2 df_X2 Prob_X2; format G2 f9.2 X2 f9.2 Prob_G2 f7.4 Prob_X2 f6.4; title 'Chi-square-test for Item fit' ; title2"K? "Resampling based (# of replication is &n_rep )"; run;"" proc print data=_IRTTest noobs; var item_no name G2 X2; format G2 f9.2 X2 f9.2; title 'Chi-square-test for Item fit'; title2 "No P-values calculated since SampleTest= NO"; run;"" proc print data=_IRTTest noobs; var item_no name df G2 Prob_G2 X2 Prob_X2; format G2 f9.2 X2 f9.2 Prob_G2 f7.4 Prob_X2 f6.4; title 'Chi-square-test for Item fit'; title2 "Sum score based: &scale "; run;" options date;""%%upcase(&LD_test)=YES" options nodate; proc tabulate data=_LD_Test order=data; class name1 name2; var X2 DF Prob_X2 res_corr; table name1=' '*(X2*mean=' '*f=9.2 DF*mean=' '*f=3.0 Prob_X2='p'*mean=' '*f=6.4), name2=' ' / box='Chi-square test'; table name1=' '*"res_corr=' '*mean=' '*f=9.2, name2=' ' / box='Residual Correlation'; title 'Local Dependence tests'; run; options date;""#%upcase(&graph)=YES"*%upcase(&testmethod)^=NONE" %IRTFIT_graph(data=_IRTFreq , plotitem = &itemlist , min_pre=5 , tick_txt = YES);""*%upcase(&graph_data)^=NONE" %IRTFIT_graph(data=&graph_data , plotitem = &itemlist , min_pre=&min_pre , tick_txt = YES);""";+%upcase(&outfmt)=RTF | %upcase(&outfmt)=PDF" ods &outfmt close""7+; ods listing; title ' '; ods exclude none;"C3%upcase(&testmethod)^=NONE or %upcase(&LD_test)^=NO"4( proc datasets nolist; delete _par __par"*%upcase(&testmethod)^=NONE"" _irttest _irtfreq""%%upcase(&LD_test)^=NO" _LD_TEST""$ ; run; quit;""# options notes stimer;" "tIRTFITC9.1   G4>"0ITEMLIST"5DATA_NONE"5PARFILE_NONE"4MODELREAD"4 TESTMETHODNONE"2LD_TESTNO"8SCALESUBTOTAL"1D1"1MIN_PRE5"2RESCALENO"4CRITCUT0.02"4FITBOUND2.02"2 SAMPLETESTNO"3N_REP100"2SEED-1"2GRAPHNO"4 GRAPH_DATANONE"4OUTLIBNONE"7OUTPUTLIMITED"4OUTCORE_IRT"3OUTFMTWIN"1P_MEAN0"1P_STD1"2LOWRNG-5"1HIGHRNG5"3INTV_SUM0.1"3 INTV_THETA0.5"1MINCODE1"1MISSING."1 MAXCHOICE7",OUTPUT",EXIT "v ods exclude all; options nonotes nostimer nomprint nosymbolgen nomlogic; *options mprint symbolgen; *options mprint;"q'a"%trim(%left(%upcase(&data)))"= "_NONE" and (%upcase(&testmethod)^=NONE or %upcase(&LD_test)^=NO)"@0***** ERROR: A data set must be specified *****"EXIT" ;"'"t,d"%trim(%left(%upcase(&parfile)))"= "_NONE" and (%upcase(&testmethod)^=NONE or %upcase(&LD_test)^=NO)"P@***** ERROR: An item parameter file set must be specified *****"EXIT" ;","i1Y%upcase(&testmethod)^= NONE and %upcase(&testmethod)^=THETA and %upcase(&testmethod)^=SUM"^N***** ERROR: TESTMETHOD must be specified as either NONE, THETA, or SUM *****"EXIT" ;"1"B42%upcase(&testmethod)=NONE and %upcase(&LD_test)=NO"OUTPUT"4""t************************************************ IRTFIT ANALYSES ************************************************"":&DATA ne _NONE"G7THE DATA SET (ITEM RESPONSES) IS: &DATA":"!=&PARFILE ne _NONE"J:THE ITEM PARAMETER FILE IS: &PARFILE"="&@%UPCASE(&MODEL) = READ"B2THE IRT MODEL IS READ FROM THE ITEM PARAMETER FILE"A"H8THE IRT MODEL IS: &MODEL"D4THE D CONSTANT IS SET AT: &D"J:THE ITEMS ARE ASSUMED TO HAVE A MINIMUM SCORE OF: &MINCODE"L<THE MAXIMAL NUMBER OF RESPONSES CHOICES ARE: &MAXCHOICE"(G%UPCASE(&OUTLIB) NE NONE"=-OUTPUT FILES ARE SAVED IN THE LIBRARY &OUTLIB"G ERRO! "bRTHE OUTPUT FILE NAMES ARE: &OUTCORE._FREQ AND &OUTCORE._FIT"'K%UPCASE(&LD_test) = YES"RB_ AND &OUTCORE._LD"K"&N%UPCASE(&OUTFMT) = WIN"8(OUTPUT IS SHOWN IN THE SAS OUTPUT WINDOW"T"&Q%UPCASE(&OUTFMT) = PDF",OUTPUT IS SENT TO A PDF FILE"T"&T%UPCASE(&OUTFMT) = RTF"-OUTPUT IS SENT TO AN RTF FILE"T"TDTHE SAMPLE MEAN AND SD IS ASSUMED TO BE: &P_MEAN AND &P_STD"UETHE QUADRATURE POINT RANGE IS: &LOWRNG TO &HIGHRNG",_%UPCASE(&TESTMETHOD) = THETA"M=THE STEPSIZE IS: &INTV_THETA"VFIRT FIT TESTS ARE BASED ON THE X2* and G2* FIT STATISTICS (STONE 2000)"\LTHE FIT STATISTICS ARE CALCULATED BASED ON THE RANGE -&FITBOUND TO &FITBOUND"\LCELLS WITH PREDICTED VALUES BELOW &CRITCUT ARE EXCLUDED FROM THE CALCULATION"*^%UPCASE(&SAMPLETEST) = YES"aQP-VALUES ARE CALCULATED THROUGH A MONTE-CARLO RESAMPLE PROCEDURE (&N_REP SAMPLES)"^"j"*j%UPCASE(&TESTMETHOD) = SUM"K;THE STEPSIZE IS: &INTV_SUM"dTIRT FIT TESTS ARE BASED ON THE S-X2 and S-G2 FIT STATISTICS (ORLANDO & THISSEN 2000)"*e%UPCASE(&SCALE) = SUBTOTAL"sITEM RESPONSE PROBABILITIES ARE CONDITIONED ON THE SIMPLE SUM OF ALL ITEMS IN THE SCALE EXCEPT THE ITEM IN QUESTION"h"'h%UPCASE(&SCALE) = TOTAL"gWITEM RESPONSE PROBABILITIES ARE CONDITIONED ON THE SIMPLE SUM OF ALL ITEMS IN THE SCALE"h"J:THE MINIMAL PREDICTED CELL VALUE IS: &MIN_PRE"j""u*********************************************************************************************************************"" data _null_; array _it (*) &itemlist; call symput('n_it1', left(dim(_it))); run; data _null_; set &data end=last; array _it (*) &itemlist; array _n (&n_it1); retain _n1-_n&N_it1 0; do i=1 to &n_it1; if _it[i]^=. then _n[i]=1; end; if last then do;" length itemname $16; do i=1 to &n_it1; call symput('use' || left(i), _n[i]); call vname(_it[i], itemname); call symput('_it' || left(i), upcase(itemname) ); end; end; run;"USEDITEM" " NOTUSEDITEM" "NITEMS" 0"%I1&n_it11"| &&use&i=1"NITEMS" %eval(&nitems+1)"USEDITEM"& &usedItem   &&_it&i"~" NOTUSEDITEM"6 &&NotUsedItem   %scan(&itemlist, &i)""&NotUsedItem^="\LThe following items do not have observations in &data and will not be used -" &NotUsedItem"" data _par; length model $10; set &parfile end=last; array _it (*) &UsedItem; array _n (&nitems); retain _n1-_n&nitems 0; length itemname $16; retain used 0; do i=1 to &nitems; call vname(_it[i], itemname); if upcase(name)=upcase(itemname) then do;"  used+1; _n[i]=1; end; end; ******************************************************************************** Rename and recalculate item parameters ************************************************************* "!***************" ****; array thresholds (&maxchoice) threshold1-threshold&maxchoice; array steps (&maxchoice) step1-step&maxchoice; array categories (&maxchoice) category1-category&maxchoice; do i = 1 to (choices-1); if thresholds(i) = . and steps(i)^= . then thresholds(" i) = steps(i); else if thresholds(i) = . and location^= . then do; thresholds(i) = location-categories(i); if choices = 2 then thresholds(i) = location; end; end; if slope= . then slope=1; if guess= . then guess=0; if last then do; call symput("nb'used', used); do i=1 to &nitems; call symput('use' || left(i), _n[i]); end; end; run;" &used<&nitems"L<Macro stops because following item(s) do not have parameters"&I1&nitems1" &&use&i=0"$%scan(&usedItem, &i)"""""  ****************************************************************************************** * For RSM and GRSM models calculate number of category parameters to be estimated ****************************************************************************"**************;"_MRPARS" 0"  data _null; set _par (where= (upcase(trim(left(model))) = 'RSM' or upcase(trim(left(model))) = 'GRSM')) end=last; array thresholds (&maxchoice) threshold1-threshold&maxchoice; array categories (&maxchoice) category1-category&maxchoice; location = mean(" of threshold1-threshold&maxchoice); retain _npars (0); _nratingi = _N_; _unequal = 0; do _i = 1 to choices-1; Categories(_i) = location - thresholds(_i); if lag1(categories(_i)) = . or abs(categories(_i) - lag1(categories(_i)) ) > 0.001 then _unequal = 1;" end; _npars = _npars + (choices-1)*_unequal; if last then do; _mpars = _npars/_nratingi; call symput('_mrpars', trim(left(_mpars)) ); end; run;" _MODELCHECK" OK"  data __par; length itemname $12 model $10 slope guess threshold1-threshold&maxchoice slope1-slope&maxchoice intercept1-intercept&maxchoice 8; set _par end=last; array _it (*) &UsedItem; array thresholds (&maxchoice) threshold1-threshold&maxchoice" ; array slopes (&maxchoice) slope1-slope&maxchoice; array intercepts (&maxchoice) intercept1-intercept&maxchoice; retain _maxchoice 0; do i=1 to &nitems; call vname(_it[i], itemname); if trim(upcase(name))=trim(upcase(itemname)) then do;"  call symput('_it'||trim(left(put(i,4.))), trim(left(upcase(name)))); if model='' then model = "&model"; model=trim(left(upcase(model))); if model = 'READ' then call symput('_modelcheck',"  'MISSING'); if model ^= 'GRM' and model ^= 'GPCM' and model ^= 'PCM' and model ^= 'GRSM' and model ^= 'RSM' and model ^= 'NOM' and model ^= 'DI1P'"  and model ^= 'DI2P' and model ^= 'DI3P' then call symput('_modelcheck', 'ERROR'); call symput('model'||trim(left(put(i,4.))), left(model)); call symput('itch'||trim(left(put(i,4.)" )), left(choices)); if _maxchoice>@>h>T???@@AAABCCCCDDDDEEEEFFTFFFFG0GXGtGGGGG