From fed49f4ab07f41a48b00c2ad60cd8591826c8eb5 Mon Sep 17 00:00:00 2001 From: Joseph Luchman Date: Fri, 27 Jan 2023 11:07:57 -0600 Subject: [PATCH] Patch update to 3.4.1 --- domin.ado | 30 +++++++++++++++-------- domin.sthlp | 2 +- dominance.mata | 59 +++++++++++++++++++++++++++++----------------- lb_dominance.mlib | Bin 292496 -> 293232 bytes 4 files changed, 59 insertions(+), 32 deletions(-) diff --git a/domin.ado b/domin.ado index 8ae5417..4cf5010 100644 --- a/domin.ado +++ b/domin.ado @@ -1,4 +1,4 @@ -*! domin version 3.4.0 11/3/2022 Joseph N. Luchman +*! domin version 3.4.1 1/27/2023 Joseph N. Luchman program define domin, eclass //history and version information at end of file @@ -366,14 +366,19 @@ else { mata: model_specs = domin_specs() - mata: model_specs.iv_string = st_local("ivs") - mata: model_specs.cdlcompu = st_local("conditional'") - mata: model_specs.cptcompu = st_local("complete") mata: model_specs.mi = st_local("mi") - mata: model_specs.all_subsets_fitstat = st_numscalar(st_local("allfs")) - mata: model_specs.constant_model_fitstat = st_numscalar(st_local("consfs")) - - mata: dominance(model_specs, &domin_call()) //invoke "dominance()" function in Mata + mata: model_specs.reg = st_local("reg") + mata: model_specs.dv = st_local("dv") + mata: model_specs.all = st_local("all") + mata: model_specs.weight = st_local("weight") + mata: model_specs.exp = st_local("exp") + mata: model_specs.touse = st_local("touse") + mata: model_specs.regopts = st_local("regopts") + + mata: dominance(model_specs, &domin_call(), /// + st_local("conditional'"), st_local("complete"), /// + st_local("ivs"), /// + st_numscalar(st_local("allfs")), st_numscalar(st_local("consfs"))) //invoke "dominance()" function in Mata /*translate r-class results into temp results*/ matrix `domwgts' = r(domwgts) @@ -706,7 +711,7 @@ end -greatly expanded, clarified, and updated the help file ----- - domin version 3.1 - date - Apr 14, 2015 --updated epsilon - works with glm, mvdom, and regress; also migrated to Mata (though not recommended approach - weights nixed for esplilon) +-updated epsilon - works with glm, mvdom, and regress; also migrated to Mata (though not recommended approach - weights nixed for epslilon) -reverse option to reverse "coding" of fitstat in ranks, standardized metric and complete dominance -fixed tied ranks (used to randomly assign, - now share highest number) -added "best dominance" - Com, Cond, Gen - in display (works with "reverse") @@ -732,8 +737,13 @@ end -clean up internal functions (naming and redundancy) -update to terminology in documentation and reporting --- - domin version 3.4.0 - mth, day, 20xx + domin version 3.4.0 - November 3, 2022 - reorganization of Mata code; function to function passing; Mata struct to handle input specs - lb_dominance.mlib now contains all complied Mata code for -domin- generalized for accommodating -domme- and future commands - increased precision of passed 'all' and 'constant' fit stats + // 3.4.1 - January 27, 2023 + - fixed Mata code (dominance.mata 0.0.1) + - increase flexibility to work with -domme-; 3.4.0 makes assumptions -domme- cannot meet + - does not force arguments but accepts single objects for command-specific needs + - records domin options directly (doesn't call them as local macros) */ diff --git a/domin.sthlp b/domin.sthlp index 559761f..63c7887 100644 --- a/domin.sthlp +++ b/domin.sthlp @@ -1,5 +1,5 @@ {smcl} -{* *! version 3.4.0 November 3, 2022 J. N. Luchman}{...} +{* *! version 3.4.1 January 27, 2023 J. N. Luchman}{...} {cmd:help domin} {title:Title} diff --git a/dominance.mata b/dominance.mata index 29c271b..a706421 100644 --- a/dominance.mata +++ b/dominance.mata @@ -1,4 +1,4 @@ -*! dominance.mata version 0.0.0 11/3/2022 Joseph N. Luchman +*! dominance.mata version 0.0.1 1/27/2023 Joseph N. Luchman version 12.1 @@ -9,9 +9,7 @@ mata set matastrict on struct domin_specs { - string scalar iv_string, cdlcompu, cptcompu, mi - - real scalar all_subsets_fitstat, constant_model_fitstat + string scalar mi, reg, dv, all, weight, exp, touse, regopts } @@ -22,20 +20,29 @@ mata: mata set matastrict on -void dominance(struct domin_specs scalar model_specs, pointer scalar model_call) +void dominance(struct domin_specs scalar model_specs, pointer scalar model_call, /// + string scalar cdlcompu, string scalar cptcompu, string scalar iv_string, /// + real scalar all_subsets_fitstat, real scalar constant_model_fitstat) { /*# object declarations*/ - real matrix IV_antiindicator_matrix, conditional_dominance, weighted_order_fitstats, weighted_order1less_fitstats, weight_matrix, complete_dominance, select2IVfits, IV_indicator_matrix, sorted_two_IVs, compare_two_IVs + real matrix IV_antiindicator_matrix, conditional_dominance, /// + weighted_order_fitstats, weighted_order1less_fitstats, /// + weight_matrix, complete_dominance, select2IVfits, /// + IV_indicator_matrix, sorted_two_IVs, compare_two_IVs string matrix IV_name_matrix - real rowvector fitstat_vector, orders, combin_at_order, combin_at_order_1less, general_dominance, standardized, focal_row_numbers, nonfocal_row_numbers, cpt_desig, indicator_weight, antiindicator_weight + real rowvector fitstat_vector, orders, combin_at_order, /// + combin_at_order_1less, general_dominance, standardized, /// + focal_row_numbers, nonfocal_row_numbers, cpt_desig, /// + indicator_weight, antiindicator_weight real colvector binary_pattern, cdl3, cpt_setup_vec, select2IVs string colvector IVs - real scalar number_of_IVs, number_of_regressions, display, fitstat, var1, var2, x, y + real scalar number_of_IVs, number_of_regressions, display, fitstat, /// + var1, var2, x, y string scalar IVs_in_model @@ -44,7 +51,7 @@ void dominance(struct domin_specs scalar model_specs, pointer scalar model_call) /*parse the predictor inputs*/ t = tokeninit(wchars = (" "), pchars = (" "), qchars = ("<>")) //set up parsing rules - tokenset(t, model_specs.iv_string) //register the "iv_string" string scalar for parsing/tokenizing + tokenset(t, iv_string) //register the "iv_string" string scalar for parsing/tokenizing IVs = tokengetall(t)' //obtain all IV sets and IVs as a vector @@ -127,8 +134,9 @@ void dominance(struct domin_specs scalar model_specs, pointer scalar model_call) } IVs_in_model = invtokens(IV_name_matrix[., x]') //collect a distinct subset of IVs, then collpase names into single string separated by spaces - - fitstat = (*model_call)(model_specs.mi, IVs_in_model, model_specs.all_subsets_fitstat, model_specs.constant_model_fitstat) + + fitstat = (*model_call)(IVs_in_model, all_subsets_fitstat, /// + constant_model_fitstat, model_specs) //implement called model - will differ for domin vs. domme fitstat_vector[1, x] = fitstat //add fitstat to vector of fitstats @@ -154,7 +162,7 @@ void dominance(struct domin_specs scalar model_specs, pointer scalar model_call) general_dominance = colsum((weight_matrix:*fitstat_vector)') //general dominance weights created by computing product of weights and fitstats and summing for each IV row-wise; in implementing the rows are transposed and column summed so it forms a row vector as will be needed to make it an "e(b)" vector - fitstat = rowsum(general_dominance) + model_specs.all_subsets_fitstat + model_specs.constant_model_fitstat //total fitstat is then sum of gen. dom. wgts replacing the constant-only model and the "all" subsets stat + fitstat = rowsum(general_dominance) + all_subsets_fitstat + constant_model_fitstat //total fitstat is then sum of gen. dom. wgts replacing the constant-only model and the "all" subsets stat st_matrix("r(domwgts)", general_dominance) //return the general dom. wgts as r-class matrix @@ -167,7 +175,7 @@ void dominance(struct domin_specs scalar model_specs, pointer scalar model_call) st_numscalar("r(fs)", fitstat) //return overall fit statistic in r-class scalar /*compute conditional dominance*/ - if (strlen(model_specs.cdlcompu) == 0) { + if (strlen(cdlcompu) == 0) { if (number_of_IVs > 5) printf("\n\n{txt}Computing conditional dominance\n") @@ -189,7 +197,7 @@ void dominance(struct domin_specs scalar model_specs, pointer scalar model_call) } /*compute complete dominance*/ - if (strlen(model_specs.cptcompu) == 0) { + if (strlen(cptcompu) == 0) { if (number_of_IVs > 5) printf("\n{txt}Computing complete dominance\n") @@ -239,21 +247,26 @@ void dominance(struct domin_specs scalar model_specs, pointer scalar model_call) end -/*Mata function to execute 'domin-flavored' models*/ -version 12 +**# Mata function to execute 'domin-flavored' models +version 12.1 mata: mata set matastrict on - real scalar domin_call(string scalar mi, string scalar IVs_in_model, real scalar all_subsets_fitstat, real scalar constant_model_fitstat) + real scalar domin_call(string scalar IVs_in_model, + real scalar all_subsets_fitstat, real scalar constant_model_fitstat, /// + struct domin_specs scalar model_specs) { real scalar fitstat - if (strlen(mi) == 0) { //if not multiple imputation, then regular regression + if (strlen(model_specs.mi) == 0) { //if not multiple imputation, then regular regression - stata("\`reg' \`dv' \`all' " + IVs_in_model + " [\`weight'\`exp'] if \`touse', \`regopts'", 1) //conduct regression + stata(model_specs.reg + " " + model_specs.dv + " " + /// + model_specs.all + " " + IVs_in_model + " [" + /// + model_specs.weight + model_specs.exp + "] if " + + model_specs.touse + ", " + model_specs.regopts, 1) //conduct regression fitstat = st_numscalar(st_local("fitstat")) - all_subsets_fitstat - constant_model_fitstat //record fitstat omitting constant and all subsets values; note that the fitstat to be pulled from Stata is stored as the Stata local "fitstat" @@ -261,7 +274,11 @@ mata: else { //otherwise, regression with "mi estimate:" - stata("mi estimate, saving(\`mifile', replace) \`miopt': \`reg' \`dv' \`all' " + IVs_in_model + " [\`weight'\`exp'] if \`keep', \`regopts'", 1) //conduct regression with "mi estimate:" + stata("mi estimate, saving(\`mifile', replace) \`miopt': " + /// + model_specs.reg + " " + model_specs.dv + " " + /// + model_specs.all + " " + IVs_in_model + " [" + /// + model_specs.weight + model_specs.exp + "] if " + + model_specs.touse + ", " + model_specs.regopts, 1) //conduct regression with "mi estimate:" stata("mi_dom, name(\`mifile') fitstat(\`fitstat') list(\`=e(m_est_mi)')", 1) //use built-in program to obtain average fitstat across imputations @@ -275,7 +292,7 @@ mata: end -/*Mata function to execute epsilon-based relative importance*/ +**# Mata function to execute epsilon-based relative importance version 12.1 mata: diff --git a/lb_dominance.mlib b/lb_dominance.mlib index 79c4db3329e1ec314a31dcdb7d638c6eeed0f8e2..62802d92fae1db4494b6c7984554274d072b95c5 100644 GIT binary patch literal 293232 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

~mY* z_D>H-F|eJf+w!(=rf$otUAN_FzdO?X%yw_f(=oZfy)ECjzr8J=&_7eR?>L$FsEuUaByK9rqeDb9|&r9BXmr=Fd@QJ2uaaz~wC|$%!^`up3{uipTdTFGn!^X-fRx znzH;Dzq{V$SM#nscxlIn`LKV;hqWQUNqc}k>}!q-sV9e-m!-s~J6HJBJednGyWO$Q zXHS3E{)V*4=~3#@?ah4XKmnkYfAdrFAt|&jPC6z8RJld`P81J@4fr< zVgG>$pR#AnNjWnY><>n2e?K+#$}!_KepT}9Eku&zEbF>o{y&=FcT;rCli2(q#<;8} z^CAvBYX10N=p30tF(nRjBQCku{$LNiIKr6Ze{}?#nhWbfn-3*+Tah!7xd?WLBg~;< zFQpDM#%HYf%zQQ_{p?X}UlFO;kohzP$)_a;8qnnq_U~-p7`DN_;A>L#fw%s1xgh zDY2tXZsW1A`EYB)c+8>V!4>8Rd-5fb*$6iK#rkOaDlcqa9vRP_Hhp(Q;KbUpUU^>U zYW-kN9&b$9K5w(1OPzclPKp1a2>x9z_;E&!e^0^pV1(Sp_eRZ^b)~=76Q7G(9eM;N zFnlzh%%fq3fAVeoswBUK2y?CdQ)ASbkL}S&<~Y5aa%NON>z6K!K|Wm{)`{ofXkTMvo119$U+~=SP?E=2=tx z4@E9yEuR#7V&0sx_9$`4m7KccVgncK#`gt%JdcUh?D3bTBoEe(9P!z29cz5Xt@Cdo z^{mbOwJFJg7(6@JRNP+b^wmD3o&K}dy3P>BKN=wiE~#mkZ^b0;@d)#HdfVSi$+L7U z(v3|V@*zgoc9LE7SDri<@WPi|x^eMG-;K??9_{NR>|yeIN~HE5b>=`HbKv{0=2v~_ zkvB!UyuXt+e%%}x|JRAn*sqS9Zye^uToxkC1wV3U{L)nn^skCAPu};LOV{pvzC1%+ z-x~X}=xYq#8HvL>vG+JvXfqCLNFAGMcm0;4=UL*pS&SsVx$0n^=3dR~DVN(i$4x(y1e)WFk`I~i`9slj6eH_{QAs`bn~je8>V129 z{@xWGk6!&1Gi{`Q|JH8baP#yIY|1wA@*flJG=3rWp>&;sQQ)2Z`;FhpqLB%oWOde} pjkLd)`UW~HmQPb>#j4JVRh<=U>$A0D)yIleU#(cRYsJ!@{a>-*j*$QW delta 7623 zcmds+O>9)x702Jq+%Yx;uxYSk4EB&oFyI782rf#EYd&KGfn`&mUt9 zt<;$@@O$~Ey~90JzblF&F{6Pn z9vLW%6%H1nIexgqH7)BBd8JSg<_IYvCqVmw-?iE0Q)m3}X4kX{BaaA3Wx~8dqZ7~? z6wvyyFxk@iqNQK>y|T3YSCaU)&?caX^aShv4_jQz3y`xy?`U6tbFTOBN&RzhaIiTi z+FT*`a_{SX1N}z}&Aol6Mw+{G14nYbh2axpea(;MP#PX7j5QZc+o@~(cec9qo9@Zv zt9^YVNsE4XtJ`0Zz9AQ``QL7x67tk8-?7crrT#}EJY6h^@NB~?*|ddM^BUj2)vcR0 z!ey;aiSYhs+`gvkwNZ410?;q30=ZOiN%eM3^+w61-|2BJS4TVDM{azZq!6V1fUQ@B z^^U+_t#!T7B2dEUs6e7~g8kq>CQy**Gg67j!FybwXgdYUe`yqLiJl9Kyhem=6f>@L z6hO5=>3*mMa`0n$pX+mttx=~uS`cJDm@FfDx4>Q#bqjs2WdmFG3TDzq=%_UbtujAR z^>=+PKaf}5jIB?|4ce(z zAfL%DqAzCsZ-(5Gag#BR&HVF{!4=%h2y9a&luH1-r0bS|Mx_;<*YBFg9|{6VB^--0sF8CM1J=kU9W@ya&?DejGS**&SVKo9xkosJe}AJ}JY*+& zQbHsH!_amLoq~c|iiq)WggQokpFkb25ulkon{xV>1?L|L4bhbzT9n)S~PxcW?VT9adLbrs6R zJ>DH~`B&y^Y4%7XEE}o9YJoDlDSPGi`Z(~CdR@}NzqYJje$3U@GOrP^g*?6$U0O44 z=iqD>0&H183Hn-rByjFW1$*#hG{>(bjfb4^NfLZ?M}*e}_|S8L&OTl`bdLxGq*A~E zl+K64kqiR0Nx%t_<2A+!6uil0Yb8z@!24W4&yu-N^XIgG?7&P$FwPxevvS6&#oH?& z+bgg}o=q58V*}@n7FXEOKrpZL@`x4i)D(?Z7icEKIu~f17CF+{uJ}Hykub9%cINxt zgRWsaRX{MF5D2hkimc=kYs(Po(5aX+B4Vn>ceJ~@4e?Y<#++a~@7G0o zFf2=Ctvdx=-~)tOU<>2h7Ss*zJSI$)alzI*35r@o(!XfVO|4RGMa@N`ZfV)b_+O@ zlq;|6-_u^>+;p?mtvT}4FbDivC1!^re$0`rpUO(xr4kkw-! zBRnY0=xjE@_?I%ygX4bm&;fh+l&4zE2|UdSR15+uh0DRYIq?Qlvj;$lzSPe_Y`L0ia@AJ(hFdPi8V)<}{4xBH3IhjN1BmOlFFCz>`8 znNSO<4gTB6J>VKrr~U3@u4Pguagf(ax%87}OZiRBam1=GxzWdg zXJvz4mp~fYeD0X~B~43yA&y_MLu3`-tqBV5)o{5%0`X#9|!!i0m6db&AyKm|cjJ3nn`d1l~qu6-;+gV;TRKVVA$(Mk3xK zdC$p#-j-SWNLiuvY#NE5j@+%0_~XdTjYRzEK`C(gW^N=pUi(is5_PFopBuf8KBB3p znD3q^uX&A=t7+PZIMDamMr2$4g;CdJT|{iEJ8VT+D_`#Gu%>j%bP*-J9?2kADe(H! z_nm7CG<%p#vY*vHaTgI^=6l%$<6p}7UAl-V&Y2#2fn*m^dhF%IuxB-Q>v9k-b`e+A zMa)lUM`Y@NuQ}=JyO8BqD{x|dRQl$47DW$h+!5xo7wro3H5$3B{GJkC@MllD{&5+O zKaL^a4nLzY@-sS>&9i9WWY1V(bl`Zu=0-boc<|8h(8vjq?$AaG6KKc|4HWqtLw{r& z?-@Js%2;1vtjGSegAl