*! version 1.0.1 9Dec2015 * Doug Hemken, Social Science Computing Coop * Univ of Wisc - Madison * update 9Dec2015 fixed a missing space typo in lines 230 and 291 thanks to Estie Hudes program stdParm, rclass version 13 syntax [, nodepvar store replace *] // options for estimates table are allowed // check that estimate storage names are not already in use quietly estimates dir local storenames "`r(names)' Original Centered Standardized" local storedups : list dups storenames if "`storedups'" != "" & "`replace'" == "" { display "{error: Estimate store(s) `storedups' cannot be overwritten}" display " Try using the {cmd:replace} option." exit } estimates store Original // mark sample tempvar touse mark `touse' if e(sample) // mean and sd of depvar quietly summarize `e(depvar)' if `touse' tempname depvarmean depvarsd // exclude the dependent variable for some models if "`e(cmd)'" == "regress" { if "`depvar'" == "" { scalar `depvarmean' = r(mean) scalar `depvarsd' = r(sd) } else { scalar `depvarmean' = 0 scalar `depvarsd' = 1 } } else if "`e(cmd)'" == "logit" | "`e(cmd)'" == "logistic" { display "Assuming option {cmd:nodepvar}" scalar `depvarmean' = 0 scalar `depvarsd' = 1 } else if "`e(cmd)'" == "glm" { if "`e(varfunct)'" == "Gaussian" & "`e(linkt)'" == "Identity" { if "`depvar'" == "" { scalar `depvarmean' = r(mean) scalar `depvarsd' = r(sd) } else { scalar `depvarmean' = 0 scalar `depvarsd' = 1 } } else if "`e(varfunct)'" == "Bernoulli" & "`e(linkt)'" == "Logit" { display "Assuming option {cmd:nodepvar}" scalar `depvarmean' = 0 scalar `depvarsd' = 1 } else { if "`depvar'" == "" { display "Failure to specify option {cmd:nodepvar} where needed will cause errors." scalar `depvarmean' = r(mean) scalar `depvarsd' = r(sd) } else { scalar `depvarmean' = 0 scalar `depvarsd' = 1 } } } else { display "{error: Only valid after {cmd:regress, logit, logistic, or glm}}" display " Try using the stdBeta package, instead." exit } // make a copy of the coefficient vector tempname BO BC BS // for coefficient vectors matrix `BO' = e(b) // find which terms are polynomial effects local terms: colnames e(b) tempname PO effectorder `terms' matrix `PO' = r(Polynomial) // separate factor and continuous parts of varnames fvseparate `terms' // rename elements of the coefficient vector matrix coleq `BO' = `r(eqstripe)' matrix colnames `BO' = `r(colstripe)' tempname C S // initialize centering matrix, C tempname ncol scalar `ncol' = colsof(`BO') matrix `C' = J(`ncol', `ncol', 0) matrix coleq `C' = `r(eqstripe)' matrix roweq `C' = `r(eqstripe)' matrix colname `C' = `r(colstripe)' matrix rowname `C' = `r(colstripe)' // initialize standardizing matrix, S matrix `S' = I(`ncol') matrix coleq `S' = `r(eqstripe)' matrix roweq `S' = `r(eqstripe)' matrix colname `S' = `r(colstripe)' matrix rowname `S' = `r(colstripe)' // generate matrix of centering coefficients, Ck // and matrix of standardizing coefficients, Sk csmatrices `r(cvars)' if `touse', po(`PO') tempname Ck Sk matrix `Ck' = r(Ck) matrix `Sk' = r(Sk) // for every row of C and S, distribute values of Ck and Sk forvalues i = 1/`=`ncol'' { tempname A B D E // pick a row in the target matrix `A' = `C'[`i', ....] local Areq: roweq `A' local Arname : rowname `A' local Arname : subinstr local Arname "(none)" "_cons" local Arname : subinstr local Arname "co." "c.", all local Arname : subinstr local Arname "o." "c.", all // find the matching row in the source matrix `D' = `Ck'["`Arname'", ....] // a quick detour to construct S matrix `S'[`i',`i'] = `Sk'["`Arname'", "`Arname'"] forvalues j = 1/`=`ncol'' { // pick a column in the target matrix `B' = `A'[...., `j'] local Bceq: coleq `B' local Bcname : colname `B' local Bcname : subinstr local Bcname "(none)" "_cons" local Bcname : subinstr local Bcname "co." "c.", all local Bcname : subinstr local Bcname "o." "c.", all // find the matching column in the source matrix `E' = `D'[...., "`Bcname'"] if "`Areq'" == "`Bceq'" { matrix `C'[`i', `j'] = `E' } } } matrix `BC' = `C'*e(b)' matrix `BC'[`ncol',1] = `BC'[`ncol',1] - `depvarmean' // find the variance of the centered parameters tempname VC VS matrix `VC' = `C'*e(V)*`C'' ecenter, bc(`BC') vc(`VC') estimates store Centered quietly estimates restore Original // find the variance of the standardized parameters matrix `BS' = (1/`depvarsd')*`S'*`BC' matrix `VS' = (1/`depvarsd'^2)*`S'*`VC'*`S'' estd, bs(`BS') vs(`VS') estimates store Standardized quietly estimates restore Original estimates table Original Centered Standardized, modelwidth(12) `options' // clean up if "`store'" == "" { estimates drop Original Centered Standardized } // return tranformation matrices return matrix S = `S' return matrix C = `C' end program effectorder, rclass version 13 syntax anything(name=terms) // initialize matrices to be returned tempname EO PO local nterms: word count `terms' matrix `EO' = J(3, `nterms', 0) matrix colnames `EO' = `terms' matrix rownames `EO' = factororder covariateorder total local vars : subinstr local terms "_cons" "" unopvar `vars' local vars `r(varlist)' local nvar : word count `vars' matrix `PO' = J(`nvar', `nterms'+1, 0) matrix colnames `PO' = `terms' max matrix rownames `PO' = `vars' local i = 0 foreach term of local terms { // for each coefficient name local i = `i' + 1 // initialize macros for this term local pvars local fvars local order = 0 // examine this term's parts _ms_parse_parts `term' if "`r(type)'" == "variable" { matrix `EO'[3, `i'] = 1 if "`r(name)'" == "_cons" { matrix `EO'[1, `i'] = 1 } else { matrix `EO'[2, `i'] = 1 local row : list posof "`r(name)'" in vars matrix `PO'[`row', `i'] = 1 } } else if "`r(type)'" == "factor" { matrix `EO'[3, `i'] = 1 matrix `EO'[1, `i'] = 1 local row : list posof "`r(name)'" in vars matrix `PO'[`row', `i'] = 1 } else if "`r(type)'" == "interaction" { matrix `EO'[3, `i'] = `r(k_names)' forvalues j = 1/`r(k_names)' { if "`r(op`j')'" == "c" | "`r(op`j')'" == "co" { local pvars `pvars' `r(name`j')' local order = `order' + 1 } else { local fvars `fvars' `r(name`j')' } } matrix `EO'[2, `i'] = `order' matrix `EO'[1, `i'] = `r(k_names)' - `order' // find higher order vars local cvars : list uniq pvars foreach cvar of local cvars { local notrepeats : subinstr local pvars "`cvar'" "", all local notrepn : word count `notrepeats' local row : list posof "`cvar'" in vars matrix `PO'[`row', `i'] = `order' - `notrepn' } foreach fvar of local fvars { local row : list posof "`fvar'" in vars matrix `PO'[`row', `i'] = 1 } } } // Find the maximum polynomial for each variable forvalues j = 1/`nterms' { forvalues i = 1/`nvar' { if el(`PO', `i', `j') > el(`PO', `i', `nterms'+1) { matrix `PO'[`i', `nterms'+1] = `PO'[`i', `j'] } } } return matrix Polynomial = `PO' return matrix Order = `EO' end program fvseparate, rclass version 13 syntax anything(name=terms) local cvars local fvars foreach term of local terms { _ms_parse_parts `term' if "`r(type)'" == "factor" { local eqstripe `eqstripe' `term' local colstripe `colstripe' (none) local fvars `fvars' `term' } else if "`r(type)'" == "variable" { local eqstripe `eqstripe' (none) local colstripe `colstripe' `term' local cvars `cvars' `term' } else if "`r(type)'" == "interaction" { local cv local fv forvalues i = 1/`r(k_names)' { if "`r(op`i')'" == "c" | "`r(op`i')'" == "co" { if "`cv'" == "" { local cv `r(op`i')'.`r(name`i')' } else { local cv `cv'#`r(op`i')'.`r(name`i')' } local cvars `cvars' `r(op`i')'.`r(name`i')' } else { if "`fv'" == "" { local fv "`r(op`i')'.`r(name`i')'" } else { local fv "`fv'#`r(op`i')'.`r(name`i')'" } local fvars `fvars' `r(op`i')'.`r(name`i')' } } if "`fv'" == "" { local fv (none) } if "`cv'" == "" { local cv (none) } local eqstripe `eqstripe' `fv' local colstripe `colstripe' `cv' } } local cvars : list uniq cvars local fvars : list uniq fvars local fterms : list uniq eqstripe return local colstripe `colstripe' return local eqstripe `eqstripe' return local fterms `fterms' return local fvars `fvars' return local cvars `cvars' end program csmatrices, rclass version 13 syntax anything(name=cvars) [if], po(name) *matrix dir *matrix list `po' // find which variables to standardize local cvars : subinstr local cvars "_cons" "" unopvar `cvars' local cv `r(varlist)' display "Recentering and rescaling: `cv'" // find means and standard deviations if "`cv'" != "" { quietly tabstat `cv' `if', stat(mean sd) save tempname M matrix `M' = r(StatTotal) } // set up initial C and S matrices for each variable local i = 0 foreach var of local cv { local ++i tempname C`var' S`var' matrix `C`var'' = (1,`M'[1,`i']\0,1) matrix `S`var'' = (1,0\0,`M'[2,`i']) matrix colnames `C`var'' = _ `var' matrix colnames `S`var'' = _ `var' } foreach var of local cv { tempname PM order matrix `PM' = `po'["`var'","max"] scalar `order' = `PM'[1,1] if `order' >=2 { kronpoly `C`var'' `order' matrix `C`var'' = r(CP) kronpoly `S`var'' `order' matrix `S`var'' = r(CP) } } tempname Ck Sk matrix `Ck' = (1) matrix `Sk' = (1) foreach var of local cv { matrix `Ck' = `C`var'' # `Ck' matrix `Sk' = `S`var'' # `Sk' local cn : colfullnames `Ck' local cn :subinstr local cn ":" "#", all local cn :subinstr local cn "#c1" "", all matrix colnames `Ck' =`cn' matrix colnames `Sk' =`cn' } local cn :subinstr local cn "c1" "_cons" if "`cn'" == "" { local cn _cons } matrix colnames `Ck' = `cn' matrix coleq `Ck' = "" matrix rownames `Ck' = `cn' matrix roweq `Ck' = "" matrix colnames `Sk' = `cn' matrix coleq `Sk' = "" matrix rownames `Sk' = `cn' matrix roweq `Sk' = "" return matrix Sk = `Sk' return matrix Ck = `Ck' end * Kronecker polynomial function program kronpoly, rclass version 13 args Cvar order // Cvar is a 2x2 matrix // order is the polynomial degree to produce // and we assume order >=2 tempname CP C1 C2 matrix `CP' = `Cvar' forvalues i = 2/`=`order'' { tempname co ck scalar `co' = colsof(`CP') matrix `CP' = `Cvar' # `CP' local cn : colfullnames `CP' scalar `ck' = colsof(`CP') * add paired rows matrix `C1' = (`CP'[1..`co',....] \ J(1,`ck',0)) matrix `C2' = (J(1,`ck',0) \ `CP'[(`co'+1)...,....]) matrix `CP' = `C1' + `C2' matrix colnames `CP' =`cn' * select columns matrix `CP' = (`CP'[....,1..`co'] , `CP'[....,`ck']) local cn : colfullnames `CP' local cn : subinstr local cn ":" "#", all local cn : subinstr local cn "#_" "", all local cn : subinstr local cn "r1" "_" matrix colnames `CP' =`cn' matrix coleq `CP' = _ matrix rownames `CP' =`cn' matrix roweq `CP' = _ } return matrix CP = `CP' end program ecenter, eclass version 13 syntax , bc(name) vc(name) tempname bccopy vccopy matrix `bccopy' = `bc'' matrix `vccopy' = `vc' ereturn repost b=`bccopy' V=`vccopy' end program estd, eclass version 13 syntax , bs(name) vs(name) tempname bscopy vscopy matrix `bscopy' = `bs'' matrix `vscopy' = `vs' ereturn repost b=`bscopy' V=`vscopy' end