Dear statalisters,
I am currently trying to write a little program with the aim of automating a procedure to interpret factor analysis solution as suggested by Grice and Harris (1998) and Grice(2001), since this is not yet available in Stata. My idea was to write something like a simple postestimation command that would plot the factor score coefficient estimates in descending order and actually this works out fine.
I also want the program to be able to calculate the multiple correlations of the factors. To do that for both rotated and unrotated factor solutions one needs to distinguish these two cases by accessing the stored macro r(rtext). For example, r(rtext) would contain the string " (unrotated)" in case of an unrotated factor solution.
So far, everything works fine.
However, when running my program the local macro r(rtext) stored by factor gets overwritten. So, if no rotation has been carried out and the program is run two times in a row, it wont be able to calculate the multiple correlations in the second go.
So I thought: Why not simply store the content of factor's r(rtext) in a local macro and let the program return it again using the exact same name r(rtext). Then the program can still access this information in the second go.
And here comes the problem: I cannot manage to let Stata store the actual content of r(rtext) - for example the string " (unrotated)" - as content of r(rtext). Instead it stores the string "r(rtext)" instead.
I am pretty sure I am having a basix misunderstanding of how stata evaluated local macros or something, but I can't seem to get it fixed, so any advice will be highly appreciated.
I hope the problem gets clear when you have a look at the code. I think it is really just about the line in the beginning where the r(rtext) from factor is stored as the local macro rotation and the line in the end where the program is meant to return the content of `rotation' in as the local macro r(rtext) again.
Here comes the code:
You may find a screenshot of the return list output attached. As you can see r(rtext) does not contain the original content of factor's r(rtext) (e.g. " (unrotated)") but the string "rtext"...
I am currently trying to write a little program with the aim of automating a procedure to interpret factor analysis solution as suggested by Grice and Harris (1998) and Grice(2001), since this is not yet available in Stata. My idea was to write something like a simple postestimation command that would plot the factor score coefficient estimates in descending order and actually this works out fine.
I also want the program to be able to calculate the multiple correlations of the factors. To do that for both rotated and unrotated factor solutions one needs to distinguish these two cases by accessing the stored macro r(rtext). For example, r(rtext) would contain the string " (unrotated)" in case of an unrotated factor solution.
So far, everything works fine.
However, when running my program the local macro r(rtext) stored by factor gets overwritten. So, if no rotation has been carried out and the program is run two times in a row, it wont be able to calculate the multiple correlations in the second go.
So I thought: Why not simply store the content of factor's r(rtext) in a local macro and let the program return it again using the exact same name r(rtext). Then the program can still access this information in the second go.
And here comes the problem: I cannot manage to let Stata store the actual content of r(rtext) - for example the string " (unrotated)" - as content of r(rtext). Instead it stores the string "r(rtext)" instead.
I am pretty sure I am having a basix misunderstanding of how stata evaluated local macros or something, but I can't seem to get it fixed, so any advice will be highly appreciated.
I hope the problem gets clear when you have a look at the code. I think it is really just about the line in the beginning where the r(rtext) from factor is stored as the local macro rotation and the line in the end where the program is meant to return the content of `rotation' in as the local macro r(rtext) again.
Here comes the code:
Code:
sysuse auto, clear capture program drop fsinter *! fsinter v1.0.0, Boris Ivanov, 21Apr2017 program define fsinter, rclass version 14.2 local rotation r(rtext) if `rotation' == " (unrotated)" { // Multiple correlations for unrotated factor solution mat phi = e(Phi) mat lambda = e(L) mat S = e(C) local f=e(f) mat A = phi*lambda'*inv(S)*lambda*phi mat rho = J(`f',1,.) forvalues i=1/`f' { mat rho[`i',1]=A[`i',`i'] local rho2_f`i': display %6.3f A[`i',`i'] } mat rho_sq = J(`f',1,.) forvalues i=1/`f' { mat rho_sq[`i',1]=sqrt(A[`i',`i']) local rho_f`i': display %6.3f sqrt(A[`i',`i']) } } else { // Multiple correlations for rotated factor solution mat phi = e(r_Phi) mat lambda = e(r_L) mat S = e(C) local f=e(f) mat A = phi*lambda'*inv(S)*lambda*phi mat rho = J(`f',1,.) forvalues i=1/`f' { mat rho[`i',1]=A[`i',`i'] local rho2_f`i': display %6.3f A[`i',`i'] } mat rho_sq = J(`f',1,.) forvalues i=1/`f' { mat rho_sq[`i',1]=sqrt(A[`i',`i']) local rho_f`i': display %6.3f sqrt(A[`i',`i']) } } preserve set autotabgraphs on // Makes Stata stack the graph in tabs in the graph display window qui predict fs_* mat scoef = r(scoef) qui xsvmat, from(scoef) names(col) rownames(item) fast // Store matrix of factor score coefficients as dataset qui replace item = substr(item,1,15) // truncating item names (for marker labels) qui gen rank=. // gen var for ranking items by factor score coeff on item forvalues i=1/`f' { gsort - Factor`i' // sort factor score coeffs descendingly qui replace rank=_n // adjust the ranking variable accordingly twoway (scatter Factor`i' rank, /// msize(medium) mlab(item) mlabangle(20) mlabpos(1) mlabsize(vsmall) connect(l) /// ytitle("Factor `i' score coefficients") /// note("Factor score determinacy: " /// "{&rho} = `rho_f`i''" /// "{&rho}{superscript:2} = `rho2_f`i''", size(vsmall)) /// legend(off) /// name(factor`i', replace)) } return scalar f = `f' return matrix rho_sq = rho_sq return matrix rho = rho return local rtext `rotation' set autotabgraphs off restore end ** Lets run the program and see what it will return: qui factor price mpg rep78 gear_ratio displacement // unrotated factor solution fsinter return list qui factor price mpg rep78 gear_ratio displacement // rotated factor solution qui rotate fsinter return list
Comment