Appendix B. An SAS/IML sample program for analyzing the random split data in Example 1 PROC IML; *********** Specify the following information before running the program ***********; P = 22; * no of variables; K = 4; * no of common factors; NT = 621; * sample size of target samples; NR = 621; * sample size of replication samples; BREP = 1000; * no of bootstrap replications; alpha = .05 ; * alpha level; seed1 = 23432111; * seed for bootstrapping; seed2 = 67591012; * seed for bootstrapping; *************Read in raw data*************************; RAW_T={a NTp data set in target sample}; RAW_R={a NRp data set in replication sample}; *************Create useful matrices*********************; cols = 1:K ; percent = int(alpha*brep); * locate critical values ; ncong = P+K+1 ; * total no of cong coeff ; BOOTCONG = J(BREP,ncong,0); * save cong coeff computed from bootstrap samples; DECISION = J(1,ncong,0) ; * save decision (1=reject); CRITICAL = J(1,ncong,0) ; * save critical values ; ZZB1=J(NT,P,0) ; ZZB2=J(NR,P,0) ; *************** Subrountine 1 - Square root of a matrix by SVD ***************; start root1(a); a=sqrsym(symsqr(a)); call svd(ua,qa,va,a); ha=ua*diag(sqrt(qa))*va`; return (ha); finish root1; ***** Subrountine 2 - TARGET ROTATION & FACTOR CONGRUENCE *****; ***** Ref : McCrae et al. (1996), JPSP, p.566 ************************; start CONGRUEN; ** NORM is factor loadings matrix from target samples; ** REPL is factor loadings matrix from REPLion samples; ** VARCONG is variable congruence **; ** FCONG is factor congruence **; ** TOTCONG is total congruence **; S = REPL`*NORM; W = EIGVEC(S*S`); V = EIGVEC(S`*S); O = W`*S*V; L = DIAG(SIGN(O)); WW=W*L; T=WW*V`; PROCRUST=REPL*T; ** Computing Congruence Coefficients **; A1 = (VECDIAG(NORM`*NORM))##{.5}; A2 = (VECDIAG(PROCRUST`*PROCRUST))##{.5}; FCONG = VECDIAG((NORM`*PROCRUST)/(A1*A2`)); B1 = (VECDIAG(NORM*NORM`))##{.5}; B2 = (VECDIAG(PROCRUST*PROCRUST`))##{.5}; VARCONG = VECDIAG((NORM*PROCRUST`)/(B1*B2`)); TOTCONG = (SUM(NORM#PROCRUST))/((SSQ(NORM))#(SSQ(PROCRUST)))##{.5}; finish; * ================= Main program starts from here=================== *; MRAW_T=RAW_T[:,]; *Mean vector of RAW_T; COVRAW_T=(RAW_T`*RAW_T-NT*MRAW_T`*MRAW_T)/(NT-1); *Cov matrix of RAW_T; SDRAW_T=(diag(COVRAW_T))##.5; *Stdev of RAW_T; CORRAW_T=(SDRAW_T**-1)*COVRAW_T*(SDRAW_T**-1); *Corrln matrix of RAW_T; MRAW_R=RAW_R[:,]; *Mean vector of RAW_R; COVRAW_R=(RAW_R`*RAW_R-NT*MRAW_R`*MRAW_R)/(NT-1); *Covariance matrix of RAW_R; SDRAW_R=(diag(COVRAW_R))##.5; *Stdev of RAW_R; CORRAW_R=(SDRAW_R**-1)*COVRAW_R*(SDRAW_R**-1); *Corrln matrix of RAW_R; ********* * Factor Analysis Using Principal Components Analysis******************; * Target Samples; call eigen(EIGVAL_T,EIGVEC_T,CORRAW_T); EIGVAL_T=DIAG(EIGVAL_T); EIGVEC_T=EIGVEC_T*ROOT1(EIGVAL_T); NORM=EIGVEC_T[,cols]; * Factor matrix of Target Sample; * Replication Samples; call eigen(EIGVAL_R,EIGVEC_R,CORRAW_R); EIGVAL_R=DIAG(EIGVAL_R); EIGVEC_R=EIGVEC_R*ROOT1(EIGVAL_R); REPL=EIGVEC_R[,cols]; * Factor matrix of Replication Sample; run CONGRUEN; SAMPNORM=NORM; SAMPREPL=REPL; SAMPPROC = PROCRUST; * Procrustes-rotated factor matrix; SAMP_VAR = VARCONG`; SAMP_FAC = FCONG`; SAMP_TOT = TOTCONG; SAMPCONG = VARCONG`||FCONG`||TOTCONG; PSI_T = I(P) - DIAG(NORM*NORM`); OMEGA_T = NORM*NORM` + PSI_T ; * Implied Corr Matrix of target samples ; SIGMA_T = SDRAW_T*OMEGA_T*SDRAW_T; PSI_R = I(P) - DIAG(REPL*REPL`); OMEGA_R = REPL*REPL` + PSI_R ; * Implied Corr Matrix of replication samples ; SIGMA_R = SDRAW_R*OMEGA_T*SDRAW_R; * ================= BOOTSTRAPPING begins here =================== *; * Define Bootstrap Sampling Space *; ZZ1=RAW_T*inv(root1(COVRAW_T))*root1(SIGMA_T); *transformed target samples; ZZ2=RAW_R*inv(root1(COVRAW_R))*root1(SIGMA_R); *transformed replicatn samples; DO I=1 to BREP; ***** Bootstrapping on Target Samples ***** ; U=UNIFORM(repeat(seed1,NT,1)); U=NT*U; DO J=1 to NT; W=INT(U[J])+1; ZZB1[J,]=ZZ1[W,]; END; MZZB1=ZZB1[:,]; *Mean vector of ZZB1; COVZZB1=(ZZB1`*ZZB1-NT*MZZB1`*MZZB1)/(NT-1); *Covariance matrix of ZZB1; SDZZB1=(diag(COVZZB1))##.5; *Stdev of ZZB1; CORZZB1=(SDZZB1**-1)*COVZZB1*(SDZZB1**-1); *Corrln matrix of ZZB1; call eigen(EIGVAL_T,EIGVEC_T,CORZZB1); EIGVAL_T=DIAG(EIGVAL_T); EIGVEC_T=EIGVEC_T*ROOT1(EIGVAL_T); NORM=EIGVEC_T[,cols]; **** Bootstrapping on Replication Samples ***** ; U=UNIFORM(repeat(seed2,NR,1)); U=NR*U; DO J=1 to NR; W=INT(U[J])+1; ZZB2[J,]=ZZ2[W,]; END; MZZB2=ZZB2[:,]; *Mean vector of ZZB2; COVZZB2=(ZZB2`*ZZB2-NR*MZZB2`*MZZB2)/(NR-1); *Covariance matrix of ZZB2; SDZZB2=(diag(COVZZB2))##.5; *Stdev of ZZB2; CORZZB2=(SDZZB2**-1)*COVZZB2*(SDZZB2**-1); *Correln matrix of ZZB2; call eigen(EIGVAL_R,EIGVEC_R,CORZZB2); EIGVAL_R=DIAG(EIGVAL_R); EIGVEC_R=EIGVEC_R*ROOT1(EIGVAL_R); REPL=EIGVEC_R[,cols]; run CONGRUEN; ********** saving congruence coefficients for each bootstrap samples ***********; BOOTCONG[I,]=VARCONG`||FCONG`||TOTCONG; end; ***** Evaluate the Significance of Congruence Coefficients *****; DO L=1 to ncong ; TEMP=BOOTCONG[,L]; r=rank(TEMP); DO I=1 to BREP; IF r[I] = PERCENT THEN DO; CV = TEMP[I]; GOTO TESTING; END; END; TESTING: IF SAMPCONG[L]< CV THEN DECISION[L]=1; * 1 = significant congruence; CRITICAL[L]= CV; * Save Critical Values *; END; * ================= BOOTSTRAPPING ends here =================== *; print 'Summary of Results :' ; print 'No of variables' P; print 'No of common factors' K; print 'Sample size of target samples' NT ; print 'Sample size of replication samples' NR ; print 'Alpha level' alpha ; print 'No of Bootstrap Replications' BREP ; print 'Factor loadings matrix of target samples'; print SAMPNORM; print 'Factor loadings matrix of replication samples (before Procrustes Rotation)'; print SAMPREPL; print 'Procrutes-rotated Factor loadings matrix of replication Samples'; print SAMPPROC; print 'Sample Congruence Coefficients (variable, factor and total)'; print P 'Variable congruence coefficients'; print SAMP_VAR; print K 'Factor congruence coefficients'; print SAMP_FAC; print 'Total congruence coefficient'; print SAMP_TOT ; print 'Critical values at' alpha 'level' ; print CRITICAL; print 'Statistical decision: 1=reject; 0 = do not reject'; print DECISION;