******************************************************************************************************************************** ** First-Differences IV Estimation of the Linear Discrete-Time Hazard Model **************************************************** ******************************************************************************************************************************** *! version 2.2.0 2023-12-18 ht (option interactinst()) *! version 2.1.2 2023-12-18 ht (adjustment for cfbinout option order()) *! version 2.1.1 2023-12-12 ht (improved checks for collinearity and degenerated first-stage) *! version 2.1 2023-11-24 ht (call of cfbinout for nonlinear link function) *! version 2.0.3 2023-11-10 ht (option instruments() to allow for additional non-technical instruments) *! version 2.0.2 2023-11-08 ht (multiple-differences IV estimation) *! version 2.0.1 2023-11-07 ht (option underid added) *! version 2.0.0 2023-10-31 ht (ivregress 2sls used for linear IV estimation) *! version 1.1.3 2019-12-16 ht (egen - if possible - avoided to reduce run time) *! version 1.1.2 2019-11-14 ht (more efficient check for collinear variables) *! version 1.1.1 2019-09-12 ht (improved handling of factor-variables) *! version 1.1 2019-03-14 ht (higher-order differences considered) *! version 1.0 2019-01-29 ht *! author Harald Tauchmann *! Own-Differences IV/CF Estimation of Discrete-Time Hazard Model cap program drop xtdhazard program xtdhazard, eclass version 14 if !replay() { quietly { ** STORE COMMAND-LINE ENTRY ** local cmd "xtdhazard" local cmdline "`cmd' `*'" ** DISPLAY-FORMAT for WARNINGS ** local ls = c(linesize)-7 ** SYNTAX ** syntax /*varlist(ts fv)*/ anything [if/] [in] [pweight fweight aweight iweight/], [Difference(numlist integer >0 sort)] [noABSORBing] [Robust] [CLuster(varname)] [VCE(string)] /* */ [LEVel(real `c(level)')] [noci] [noPValues] [noOMITted] [VSQUISH] [noEMPTYcells] [BASElevels] [ALLBASElevels] [noFVLABel] [fvwrap(integer 1)] [fvwrapon(string asis)] [CFORMAT(string asis)] [PFORMAT(string asis)] /* */ [SFORMAT(string asis)] [nolstretch] /* */ [INSTRuments(varlist numeric fv ts)] /* [Link(string)] ** OPTIONS FOR LINK LINEAR ** */ [UNDerid(string asis)] [SHOWtest] [noFIRSTstage] [ASESTimator(name)] [INTERactinst] /* ** OPTIONS FOR LINK LOGIT/PROBIT/CLOGLOG ** */ [noRESGenerate] [RESName(string)] [REPLace] [Order(integer 1)] [TERza(integer 2023)] [FSKeep] [noSEARCH] [FSLink(string)] [noANAlytic] [noSANDwich] /*[noEOMITted] ** OPTIMIZATION OPTION FOR logit, probit, AND cloglog ** */ [DIFficult] [TECHnique(passthru)] [ITERate(passthru)] [TOLerance(passthru)] [LTOLerance(passthru)] [NRTOLerance(passthru)] [QTOLerance(passthru)] [NONRTOLerance] [FROM(passthru)] ** TEMPNAMES and TEMPVARS ** tempname _borg _Vorg _XdXd _XdX _G _Gsm _bsm _Vsm _bmvreg _sbmvreg _borg0d _Vorg0d _estimatorresu _newgradient _newmns _tmpgradient _tmpmns _Vorg_model _Vsm_model _rules tempvar _ly _fail _one _zero _fdesamp _ww _lhs ** MANAGE ESTIMATOR ** gettoken estimator varlist : anything if "`estimator'" != "2sls" & "`estimator'" != "logit" & "`estimator'" != "probit" & "`estimator'" != "cloglog" { noi di as error "{p 0 2 2 `ls'}{bf:`estimator'} is not a valid estimator; 2sls, logit, probit, and cloglog allowed{p_end}" exit 198 } else { if "`estimator'" == "logit" | "`estimator'" == "probit" | "`estimator'" == "cloglog" { local link "`estimator'" } else { local link "linear" } } ** CHECK IF VARLIST INCLUDES TS or FV VARIABLES ** fvrevar `varlist' `iff' `inn', list local exvarlist "`r(varlist)'" local fv : list local(varlist) === local(exvarlist) ** IDENTIFY lhs VARIABLE ** tokenize "`varlist'" local lhs "`1'" tokenize "`lhs'", parse(".") if "`2'" != "" { noi di as error "{p 0 2 2 `ls'}factor-variable and time-series operators not allowed for depvar{p_end}" exit 101 } ** CHECK PANEL-DATA DECLARATION ** _xt, treq local ivar "`r(ivar)'" local tvar "`r(tvar)'" ** MANAGE OPTION LINK ** if "`link'" == "" | "`link'" == "identity" { local link "linear" } if ("`link'" != "linear") & ("`link'" != "probit") & ("`link'" != "logit") & ("`link'" != "cloglog") { noi di as error "{p 0 2 2 `ls'}link {bf:`link'} not allowed{p_end}" exit 198 } if ("`link'" == "probit") | ("`link'" == "logit") | ("`link'" == "cloglog") { cap which cfbinout if _rc != 0 { noi display as error "{p 0 2 2 `ls'}{bf:`link'} link reqires {bf:cfbinout.ado} to be installed{p_end}" exit 198 } } ** CHECK IF RHS-VARIABLES ARE SPECIFIED ** tokenize "`varlist'" if "`2'" == "" { noi di as error "{p 0 2 2 `ls'}at least one indepvar must be specified{p_end}" exit 102 } ** HANDLE ENPTY CELLS ** set emptycells drop ** MANAGE IF if "`if'" != "" { local iff "if (`if')" } else { local iff "if (1==1)" } ** MANAGE WEIGHT ** if "`exp'" != "" { local eqs "=" } ** MANAGE OPTION DIFFERENCE ** if "`difference'" == "" { local difference = 1 } local countdiff : list sizeof local(difference) if `countdiff' > 1 { local multidiff = 1 } else { local multidiff = 0 } foreach dd in `difference' { local maxdiff = max(`dd',1) } ** MAMAGE ERRORANEOUSLY SPECIFYING vce(bootstrap) ** gettoken vceboot : vce, parse(",") local vceboot : list retokenize vceboot if "`vceboot'" == "bootstrap" | "`vceboot'" == "bootstra" | "`vceboot'" == "bootstr" | "`vceboot'" == "bootst" | "`vceboot'" == "boots" | "`vceboot'" == "boot" { noi display as error "{p 0 2 2 `ls'}vcetype {bf:`vce'} not allowed, use prefix command bootstrap{p_end}" exit 198 } ** MANAGE DEFAULT VCE OPTION ** if "`robust'" == "" & "`cluster'" == "" & "`vce'" == "" { if "`estimator'" == "2sls" { local vce "robust" } else { local vce "robust" /*"oim"*/ } } ** MANAGE OPTIONS ROBUST and CLUSTER ** if "`robust'" == "r" | "`robust'" == "ro" | "`robust'" == "rob" | "`robust'" == "robu" | "`robust'" == "robus" | "`robust'" == "robust" { local vce "robust" } if "`cluster'" != "" { local vce "cluster `cluster'" } local vce : list retokenize local(vce) tokenize "`vce'" if "`1'" == "unadjusted" | "`1'" == "unadjuste" | "`1'" == "unadjust" | "`1'" == "unadjus" | "`1'" == "unadju" | "`1'" == "unadj" | "`1'" == "unad" | "`1'" == "una" | "`1'" == "un" { local vce "unadjusted" } if "`1'" == "robust" | "`1'" == "robus" | "`1'" == "robu" | "`1'" == "rob" | "`1'" == "ro" | "`1'" == "r" { local vce "robust" } if "`1'" == "cluster" | "`1'" == "cluste" | "`1'" == "clust" | "`1'" == "clus" | "`1'" == "clu" | "`1'" == "cl" { local clustvar "`2'" local vce "cluster `clustvar'" } ** CHECK FOR INCONSISTENCY OF LINK() AND VCE() ** if ("`vce'" == "opg" | "`vce'" == "oim") & "`link'" == "linear" { noi display as error "{p 0 2 2 `ls'}vcetype {bf:`vce'} not allowed with estimator {bf:2sls}{p_end}" exit 198 } if ("`vce'" == "unadjusted") & ("`link'" != "linear") { noi display as error "{p 0 2 2 `ls'}vcetype {bf:`vce'} not allowed with estimator {bf:`link'}{p_end}" exit 198 } ** MANAGE OPTION STOREAESTIMATOR ** if "`asestimator'" == "" { local eststore "`_estimatorresu'" } else { local eststore "`asestimator'" } ** MANAGE OPTION UNDERID ** if `"`underid'"' != "" { if "`link'" != "linear" { noi display as error "{p 0 2 2 `ls'}option underid not allowed with link(`link'), no test carried out{p_end}" } cap which underid local undercheck = _rc if _rc != 0 { local underidinst noi display as error "{p 0 2 2 `ls'}option underid requires underid.ado to be installed, no test carried out{p_end}" exit 198 } else { gettoken underidcom underid2 : underid, parse(",") quotes bind gettoken komma underidopt : underid2, parse(",") quotes bind if "`showtest'" == "showtest" { local disptest "noisily" } else { local disptest "" } } } ** CHECK WETHER lhs VAR IS BINARY ** cap confirm numeric variable `lhs' if _rc != 0 { egen byte `_lhs' = group(`lhs') /*`in' `iff'*/ replace `_lhs' = `_lhs'-1 sum `_lhs' if `r(min)' != 0 | `r(max)' != 1 { noi di as error "{p 0 2 2 `ls'}depvar {bf: `lhs'} not binary{p_end}" mata : st_rclear() exit 2000 } local lhsvar "`_lhs'" } else { sum `lhs' local lmin = r(min) local lmax = r(max) count if `lhs' <. & `lhs' != `lmin' & `lhs' != `lmax' if r(N) > 0 { noi di as error "{p 0 2 2 `ls'}depvar {bf: `lhs'} not binary{p_end}" mata : st_rclear() exit 2000 } else { if `lmin' == 0 & `lmax' == 1 { local lhsvar "`lhs'" } else { gen byte `_lhs' = 0 if `lhs' == `lmin' replace `_lhs' = 1 if `lhs' == `lmax' local lhsvar "`_lhs'" } } } ** CHECK ABSORBING STATE ** gen byte `_ly' = l.`lhsvar' `iff' & !missing(`lhsvar') `in' count `iff' & (`lhsvar' == 0 & `_ly' == 1) `in' if r(N) > 0 { count `iff' & (`lhsvar' == 1 & `_ly' == 0) `in' if r(N) == 0 { noi di as error "{p 0 2 2 `ls'}recode depvar as ({bf: 1-`lhs'}){p_end}" mata : st_rclear() exit 2000 } else { noi di as error "{p 0 2 2 `ls'}variable {bf: `lhs'} does not indicate an absorbing state{p_end}" if "`absorbing'" != "noabsorbing" { mata : st_rclear() exit 198 } else { local irregular = 1 } } } ** CHECK CODING of ABSORBING STATE ** if "`absorbing'" != "noabsorbing" { gen byte `_fail' = 0 replace `_fail' = 1 if (`lhsvar' == 1 & `_ly' == 1) } else { gen byte `_fail' = 0 } local nfail "& (`_fail' != 1)" ** DE-FACTOR-VARIABLERIZE VARLIST and IDENTIFY COLLINEAR VARIABLES ** local rhsvars : list local(varlist) - local(lhs) _rmcoll `rhsvars' `iff' & (l.`lhsvar' !=.) `nfail' `inn', expand local rhsvars "`r(varlist)'" ** SAVE ORIGINAL FV-RHS-VARLIST ** local cn "`r(varlist)' _cons" local cn : list retokenize cn local kko : list sizeof local(cn) local kkom1 = `kko'-1 local kkoi = `countdiff'*`kkom1'+1 local fvinl = strpos("`cn'",".") ** GENERATE TEMPORARY VARIBLES for RHS and COLLECT NON-COLLINEAR VARS ** fvrevar `rhsvars' local expvarlist "`r(varlist)'" _rmcoll `expvarlist' `iff' & (l.`lhsvar' !=.) `nfail' `inn', expand local expvarlist "`r(varlist)'" local diffvarlist "" foreach dd in `difference' { foreach vv in `expvarlist' { gettoken prefix var : vv, parse(".") match(paren) if strpos(strreverse("`prefix'"),"o") != 1 | "`var'" == "" { local diffvarlist "`diffvarlist' D`dd'.`vv'" } else { local diffvarlist "`diffvarlist' D`dd'`vv'" } } } ** MARK TIME-INVARIATE RHS VARS AS TO BE OMITTED ** _rmdcoll `lhsvar' `diffvarlist' `iff' & (l.`lhsvar' !=.) `nfail' `inn' tokenize `r(varlist)' if `r(k_omitted)' > 0 { local newexpvarlist "" local newrhsvars "" local cc = 0 foreach vv in `expvarlist' { gettoken var rhsvars : rhsvars local cc = `cc'+1 local colex = 0 foreach dd in `difference' { if ustrrpos("``cc''","oD.") != 0 | ustrrpos("``cc''","oD`dd'.") != 0 { local colex = `colex'+1 } } if `colex' == 0 { local auxx "`auxx' `vv'" local noomc "`noomc' `cc'" } else { if strpos("`vv'",".") == 0 { local vv "o.`vv'" } else if strpos("`vv'","o.") == 0 { local vv = ustrregexrf("`vv'","\.","o\.") } if strpos("`var'",".") == 0 { local var "o.`var'" } else if (strpos("`var'","o.") == 0 & strpos("`var'","b.") == 0) { local var = ustrregexrf("`var'","\.","o\.") } } local newexpvarlist "`newexpvarlist' `vv'" local newrhsvars "`newrhsvars' `var'" } local auxx : list retokenize auxx local noomc_noc "`noomc'" local noomc "`noomc' `kko'" local expvarlist "`newexpvarlist'" local expvarlist : list retokenize local(expvarlist) local rhsvars "`newrhsvars'" local rhsvars : list retokenize local(rhsvars) } else { local nocollin "nocollin" local auxx "`expvarlist'" } if "`auxx'" == "" { **noi di as error "{p 0 2 2 `ls'}no indepvar exhibits variation over time{p_end}" noi di as error "{p 0 2 2 `ls'}all own-differences instruments collinear with `lhsvar'{p_end}" ereturn clear exit 409 } _rmcoll `rhsvars' `iff' `nfail' `inn' ** CORRESPONDENCE LIST OF auxx AND cn ** local correspauxx "" if `r(k_omitted)' > 0 { foreach pp in `noomc' { foreach oo in `cn' { local poo : list posof "`oo'" in cn if `poo' == `pp' & "`oo'" != "_cons" { local correspauxx "`correspauxx' `oo'" } } } } else { local noconsin "_cons" local correspauxx : list local(cn) - local(noconsin) } ** MANAGE OPTION INSTRUMENTS ** local instlist "" foreach dd in `difference' { local instlist "`instlist' D`dd'.(`auxx')" _rmcoll `instlist' `iff' & (l.`lhsvar' !=.) `nfail' `inn', expand local instlist "`r(varlist)'" } local ntechinst : list sizeof local(instlist) if "`instruments'" != "" { _rmcoll `instlist' `instruments' `iff' & (l.`lhsvar' !=.) `nfail' `inn', expand local oinstlist "`r(varlist)'" local oinstruments : list local(oinstlist) - local(instlist) local instlist "`oinstlist'" } if "`link'" == "linear" { ** EXECUTE ivregress 2sls ** if "`interactinst'" == "" { ivregress 2sls `lhsvar' (`rhsvars' = `instlist') `iff' `nfail' `in' [`weight' `eqs' `exp'], perfect vce(`vce') } else { ivregress 2sls `lhsvar' (`rhsvars' = c.(`instlist')##c.(`instlist')) `iff' `nfail' `in' [`weight' `eqs' `exp'], perfect vce(`vce') } estimates store `eststore' gen `_fdesamp' = e(sample) ** SAVE RESULTS FROM ivregress 2sls ** matrix `_bsm' = e(b) matrix `_Vsm' = e(V) local p = chi2tail(`e(df_m)',`e(chi2)') ** CALCULATE NUMB. of GROUPS WEIGHT-SUM and NUMB of CLUSTERS ** sort `_fdesamp' `ivar' `tvar', stable count if `_fdesamp' == 1 & (`ivar' != `ivar'[_n-1] | _n == 1) sort `ivar' `tvar', stable local mgs = r(N) if "`weight'" != "" { gen `_ww' = `exp' sum `_ww' if `_fdesamp' == 1 local wmat = r(sum) } if "`clustvar'" != "" { local N_clust = e(N_clust) } ** CALCULATE MATRIX OF FIRST-STAGE COEFFICIENTS (IF ALLOWED mvreg OTHERWISE regress) ** if "`firststage'" != "nofirststage" { local fsregc = 0 local perfectcount = 0 local perfectnum "" foreach vv in `auxx' { local fsregc = `fsregc'+ 1 if "`interactinst'" == "" { cap reg `vv' `instlist' if `_fdesamp' == 1 [`weight' `eqs' `exp'] } else { cap reg `vv' c.(`instlist')##c.(`instlist') if `_fdesamp' == 1 [`weight' `eqs' `exp'] } if `fsregc' == 1 { matrix `_Gsm' = e(b) } else { matrix `_Gsm' = (`_Gsm' \ e(b)) } if `e(r2)' == 1 { local perfectcount = `perfectcount'+ 1 local perfectnum "`perfectnum' `fsregc'" } } ** COLUMNNAMES FOR MATRIX OF FIRST-STAGE COEFFICIENTS ** local gocoln : colnames `_Gsm' local gorown "`auxx'" local gncoln "" local gnrown "" tokenize `correspauxx' foreach cc in `gocoln' { local techinst : list posof "`cc'" in local(gocoln) foreach auxv in `auxx' { local oo : list posof "`auxv'" in local(auxx) gettoken prefix var : cc, parse(".") match(paren) if (strpos(strreverse("`prefix'"),"o") != 1 & strpos(strreverse("`prefix'"),"b") != 1) | "`var'" == "" { foreach dd in `difference' { if `dd' == 1 { local dd "" } if "D`dd'.`auxv'" == "`cc'" { if `fvinl' == 0 { if `techinst' <= `ntechinst' { local gncoln "`gncoln' D`dd'.``oo''" } } else { if `techinst' <= `ntechinst' { local gncoln "`gncoln' D`dd':``oo''" } } } if "oD`dd'.`auxv'" == "`cc'" { if `fvinl' == 0 { if `techinst' <= `ntechinst' { local gncoln "`gncoln' D`dd'.``oo''" } } else { if `techinst' <= `ntechinst' { local gncoln "`gncoln' D`dd':``oo''" } } } } } } } foreach rr in `gorown' { foreach auxv in `auxx' { local oo : list posof "`auxv'" in local(auxx) if "`auxv'" == "`rr'" { local gnrown "`gnrown' ``oo''" } } } local gncoln : list retokenize local(gncoln) matrix colnames `_Gsm' = `gncoln' `oinstruments' _cons ** RENAME COLUMNS OF e(G) IF INTERACTIONS OF INSTRUMENTS ENTER FIRST-STAGE ** if "`interactinst'" == "interactinst" { local gcoloname "`gncoln' `oinstruments'" local gcoloname : list retokenize local(gcoloname) local colsg : list sizeof local(gcoloname) tokenize "`gcoloname'" local gcoliname "" forvalues ii = 1(1)`colsg' { gettoken eq2 var2 : `ii', parse(:) if "`var2'" == "" { local var2 "`eq2'" local eq2 "" } else { local var2 = ustrtoname(ustrregexra("`var2'",":",""),0) } forvalues jj = `ii'(1)`colsg' { gettoken eq1 var1 : `jj', parse(:) if "`var1'" == "" { local var1 "`eq1'" local eq1 "" } else { local var1 = ustrtoname(ustrregexra("`var1'",":",""),0) } if "`eq1'" != "" & "`eq2'" != "" { local gcoliname "`gcoliname' `eq1'#`eq2':`var1'#`var2'" } if "`eq1'" == "" & "`eq2'" != "" { local gcoliname "`gcoliname' D0#`eq2':`var1'#`var2'" } if "`eq1'" != "" & "`eq2'" == "" { local gcoliname "`gcoliname' `eq1'#D0:`var1'#`var2'" } if "`eq1'" == "" & "`eq2'" == "" { local gcoliname "`gcoliname' `var1'#`var2'" } } } local gicolname "`gcoloname' `gcoliname' _cons" local gicolname : list retokenize local(gicolname) matrix colnames `_Gsm' = `gicolname' } local gnrown : list retokenize local(gnrown) cap matrix rownames `_Gsm' = `gnrown' mat `_G' = `_Gsm' estimates restore `eststore' } mat `_borg' = `_bsm' mat `_Vorg' = `_Vsm' if "perfectnum" != "" { local perfect "" tokenize `gnrown' foreach nn in `perfectnum' { local perfect "`perfect' ``nn''" } local perfect : list retokenize local(perfect) } ** PERFORM IV TEST BY CALLING underid (Mark E. Schaffer & Frank Windmeijer) ** if `"`underid'"' != "" { if `undercheck' == 0 { estimates restore `eststore' ** CHANGE ROW & COLUMN NAMES OF e(b) and e(V) TO MAKE RESULTS FROM underid INFORMATIVE ** mata : delete_0("`_borg'", "`_Vorg'", "`_borg0d'", "`_Vorg0d'")' ereturn repost b = `_borg0d' V = `_Vorg0d', rename buildfvinfo resize ** EXECUTE underid ** cap `disptest' callunderid `underidopt' if _rc != 0 { noi di as error "{p 0 2 2 `ls'}underid failed, possibly invalid syntax{p_end}" } ** SAVE RESULTS FROM underid ** foreach rr in b_uid V_uid S_uid b0_uid b_oid V_oid S_oid b0_oid sw_uid { if "`r(`rr')'" != "" { tempname _`rr' matrix `_`rr'' = r(`rr') if "`nocollin'" != "nocollin" { tokenize `correspauxx' foreach colrow in col row { local underidn`colrow' "" local underid`colrow' : `colrow'names `_`rr'' foreach ud`colrow' in `underid`colrow'' { foreach auxv in `auxx' { local o`colrow' : list posof "`auxv'" in local(auxx) if "`auxv'" == "`ud`colrow''" { local underidn`colrow' "`underidn`colrow'' ``o`colrow'''" } foreach dd in `difference' { if `dd' == 1 { local dd "" } if "D`dd'.`auxv'" == "`ud`colrow''" { if `fvinl' == 0 { local underidn`colrow' "`underidn`colrow'' D`dd'.``o`colrow'''" } else { local underidn`colrow' "`underidn`colrow'' D`dd':``o`colrow'''" } } } } } if ("`colrow'" == "col") & (("`rr'" == "b_uid") | ("`rr'" == "V_uid") | ("`rr'" == "S_uid") | ("`rr'" == "b0_uid") | ("`rr'" == "b_oid") | ("`rr'" == "V_oid") | ("`rr'" == "S_oid") | ("`rr'" == "b0_oid")) { mat colnames `_`rr'' = `underidncol' } if ("`colrow'" == "row") & (("`rr'" == "V_uid") | ("`rr'" == "S_uid") | ("`rr'" == "V_oid") | ("`rr'" == "S_oid") | ("`rr'" == "sw_uid")) { mat rownames `_`rr'' = `underidnrow' } } } } } } } ** REPOST e(b) AND e(V) ** ereturn repost b =`_borg' V =`_Vorg', properties(b V) esample(`_fdesamp') resize buildfvinfo } ** ESTIMATE NONLINEAR BINARY OUTCOME MODEL ** else { cfbinout `link' `lhsvar' (`auxx' = `instlist') `iff' `nfail' `in' [`weight' `eqs' `exp'], vce(`vce') `replace' `resgenerate' resname(`resname') /*fslink(linear)*/ /* */ fslink(`fslink') fsswitch order(`order') terza(`terza') `fskeep' `search' `analytic' `sandwich' /* */ `difficult' `technique' `iterate' `tolerance' `ltolerance' `nrtolerance' `nonrtolerance' `nonrtolerance' `from' estimates store `eststore' gen `_fdesamp' = e(sample) ** SAVE RESULTS FROM cfbinout WHICH NEED TO BE ADJUSTED ** matrix `_bsm' = e(b) matrix `_Vsm' = e(V) matrix `_Gsm' = e(G) if "`vce'" != "opg" & "`vce'" != "oim" { matrix `_Vsm_model' = e(V_modelbased) } else { matrix `_Vsm_model' = e(V) } matrix `_tmpgradient' = e(gradient) if "`link'" != "cloglog" { matrix `_tmpmns' = e(mns) } local p = chi2tail(`e(df_m)',`e(chi2)') ** CALCULATE NUMB. of GROUPS WEIGHT-SUM and NUMB of CLUSTERS ** sort `_fdesamp' `ivar' `tvar', stable count if `_fdesamp' == 1 & (`ivar' != `ivar'[_n-1] | _n == 1) sort `ivar' `tvar', stable local mgs = r(N) if "`weight'" != "" { gen `_ww' = `exp' sum `_ww' if `_fdesamp' == 1 local wmat = r(sum) } if "`clustvar'" != "" { local N_clust = e(N_clust) } ** CORRESPONDENCE OF ROW NAMES OF e(rules) AND `_Gsm' ** cap confirm matrix e(rules) if _rc == 0 { local tmprnfs : rownames `_Gsm' local tmprnrules : rownames e(rules) local cGrule "" local nocGrule "" foreach rr in `tmprnrules' { local posrule : list posof "`rr'" in local(tmprnfs) if `posrule' != 0 { local cGrule "`cGrule' `posrule'" local nocGrule "`nocGrule' 0" } else { local nocGrule "`nocGrule' 1" } } } ** COLUMNNAMES FOR MATRIX OF FIRST-STAGE COEFFICIENTS ** local gocoln : colnames `_Gsm' local gorown "`auxx'" local gncoln "" local gnrown "" local resnamelist "" tokenize `correspauxx' if "`resname'" == "" { local resname "res" } foreach cc in `gocoln' { local techinst : list posof "`cc'" in local(gocoln) foreach auxv in `auxx' { local oo : list posof "`auxv'" in local(auxx) foreach dd in `difference' { if `dd' == 1 { local dd "" } if "D`dd'.`auxv'" == "`cc'" { if `fvinl' == 0 { if `techinst' <= `ntechinst' { local gncoln "`gncoln' D`dd'.``oo''" } } else { if `techinst' <= `ntechinst' { local gncoln "`gncoln' D`dd':``oo''" } } } if "oD`dd'.`auxv'" == "`cc'" { if `fvinl' == 0 { if `techinst' <= `ntechinst' { local gncoln "`gncoln' D`dd'.``oo''" } } else { if `techinst' <= `ntechinst' { local gncoln "`gncoln' D`dd':``oo''" } } } } } } foreach rr in `gorown' { foreach auxv in `auxx' { local oo : list posof "`auxv'" in local(auxx) gettoken prefix var : auxv, parse(".") match(paren) if strpos(strreverse("`prefix'"),"o") != 1 | "`var'" == "" { if "`auxv'" == "`rr'" { local gnrown "`gnrown' ``oo''" if "`resgenerate'" != "noresgenerate" { forvalues ss = 1(1)`order' { if `ss' == 1 { local resstorename = strtoname("`resname'_``oo''",0) if ("`replace'" == "replace") & ("`resname'_`rr'" != "`resstorename'") { cap drop `resstorename' } cap confirm variable `resname'_`rr' if _rc == 0 { rename `resname'_`rr' `resstorename' local resnamelist "`resnamelist' `resstorename'" } } else { local resstorename = strtoname("`resname'`ss'_``oo''",0) if ("`replace'" == "replace") & ("`resname'`ss'_`rr'" != "`resstorename'") { cap drop `resstorename' } cap confirm variable `resname'`ss'_`rr' if _rc == 0 { rename `resname'`ss'_`rr' `resstorename' local resnamelist "`resnamelist' `resstorename'" } } } } ** NAMES OF IN FIRST-STAGE PERFECTLY PREDICTED ENDOGENEOUS VARS ** if "`e(perfect)'" != "" { if "`oldperfect'" == "" { local oldperfect "`e(perfect)'" } gettoken op oldperfect : oldperfect if "`rr'" == "`op'" { local perfect "`perfect' ``oo''" local perfect : list retokenize local(perfect) } else { local oldperfect "`op' `oldperfect'" } } ** SWITCHES (not requited since xtdhazard always specifies fslink(linear) ** } } } } ** RETOKENIZE LIST FOR BETTER STORAGE IN e() ** local resnamelist : list retokenize local(resnamelist) local gnrown : list retokenize local(gnrown) local gncoln : list retokenize local(gncoln) matrix colnames `_Gsm' = `gncoln' `oinstruments' _cons cap matrix rownames `_Gsm' = `gnrown' mat `_G' = `_Gsm' estimates restore `eststore' ** CORRECT ROW NAMES OF e(rules) ** cap confirm matrix e(rules) if _rc == 0 { tokenize `gnrown' local counter = 0 foreach rr in `tmprnrules' { local counter = `counter'+ 1 gettoken corresprule nocGrule : nocGrule if "`corresprule'" == "1" { local newrnrules "`newrnrules' `rr'" } else { gettoken correspruleno cGrule : cGrule local newrnrules "`newrnrules' ``correspruleno''" } } mat `_rules' = e(rules) mat rownames `_rules' = `newrnrules' } ** WRITE NON-ZERO ENTRIES TO e(b) AND e(Var) AND ADJUST TO INCLUSION OF RESITUALS ** if "`resgenerate'" != "noresgenerate" { local numres : list sizeof local(resnamelist) local kkocf = `kko'+`numres' local ex_cons "_cons" local cncf : list local(cn)-local(ex_cons) local cncf "`cncf' `resnamelist' _cons" local cncf : list retokenize local(cncf) forvalues cc = 1(1)`numres' { local ccm1 = (`kko'-1)+`cc' if `cc' == 1 { local addnoomc "`ccm1'" } else { local addnoomc "`addnoomc' `ccm1'" } } local noomccf "`noomc_noc' `addnoomc' `kkocf'" } else { local kkocf = `kko' local cncf "`cn'" local noomccf "`noomc'" } if "`eomitted'" != "noeomitted" & "`nocollin'" != "nocollin" { mat `_borg' = J(1,`kkocf',0) mat colnames `_borg' = `cncf' mat `_newgradient' = J(1,`kkocf',0) mat colnames `_newgradient' = `cncf' if "`link'" != "cloglog" { mat `_newmns' = J(1,`kkocf',0) mat colnames `_newmns' = `cncf' } mat `_Vorg' = J(`kkocf',`kkocf',0) mat colnames `_Vorg' = `cncf' mat rownames `_Vorg' = `cncf' mat `_Vorg_model' = J(`kkocf',`kkocf',0) mat colnames `_Vorg_model' = `cncf' mat rownames `_Vorg_model' = `cncf' local ii = 0 foreach cc in `noomccf' { local jj = 0 local ii = `ii' +1 mat `_borg'[1,`cc'] = `_bsm'[1, `ii'] mat `_newgradient'[1,`cc'] = `_tmpgradient'[1, `ii'] if "`link'" != "cloglog" { mat `_newmns'[1,`cc'] = `_tmpmns'[1, `ii'] } foreach rr in `noomccf' { local jj = `jj' +1 mat `_Vorg'[`rr',`cc'] = `_Vsm'[`jj', `ii'] mat `_Vorg_model'[`rr',`cc'] = `_Vsm_model'[`jj', `ii'] } } } ** CHANGE ROW AND COLUMNAMES OF e(b) AND e(V) ** else { if "`nocollin'" == "nocollin" { local scn "`cncf'" } else { tokenize `cncf' foreach cc in `noomc' { local scn "`scn' ``cc''" } } mat `_borg' = `_bsm' mat colnames `_borg' = `scn' mat `_newgradient' = `_tmpgradient' mat colnames `_newgradient' = `scn' if "`link'" != "cloglog" { mat `_newmns' = `_tmpmns' mat colnames `_newmns' = `scn' } mat `_Vorg' = `_Vsm' mat colnames `_Vorg' = `scn' mat rownames `_Vorg' = `scn' if "`vce'" != "opg" & "`vce'" != "oim" { mat `_Vorg_model' = `_Vsm_model' mat colnames `_Vorg_model' = `scn' mat rownames `_Vorg_model' = `scn' } } ** CORRECT COLUMNAMES FOR OMITTED VARS ** mata : st_local("comit",strofreal(diag0cnt(diag(st_matrix("`_borg'"))))) if "`comit'" != "0" { local bcn : colfullnames `_borg' tokenize "`bcn'" local nbcn "" local bcs : colsof `_borg' forvalues cc = 1(1)`bcs' { local bb = `_borg'[1,`cc'] if `bb' == 0 { if strpos("``cc''","b.") == 0 & strpos("``cc''","o.") == 0 { if strpos("``cc''",".") != 0 { local cnrep = ustrregexrf("``cc''","\.","o\.") } else { local cnrep "o.``cc''" } } else { local cnrep "``cc''" } local nbcn "`nbcn' `cnrep'" } else { local nbcn "`nbcn' ``cc''" } } mat colnames `_borg' = `nbcn' mat colnames `_newgradient' = `nbcn' if "`link'" != "cloglog" { mat colnames `_newmns' = `nbcn' } mat colnames `_Vorg' = `nbcn' mat rownames `_Vorg' = `nbcn' if "`vce'" != "opg" & "`vce'" != "oim" { mat colnames `_Vorg_model' = `nbcn' mat rownames `_Vorg_model' = `nbcn' } } ** REPOST e(b) AND e(V) ** ereturn repost b =`_borg' V =`_Vorg', properties(b V) esample(`_fdesamp') resize buildfvinfo } ** POST RESULTS TO e() ** ereturn scalar N_g = `mgs' if `multidiff' == 0 { ereturn scalar difference = `difference' } ereturn scalar level = `level' ereturn scalar p = `p' if ("`link'" == "linear") & ("`firststage'" != "nofirststage") & ("`perfectcount'" != "") { ereturn scalar k_perfect = `perfectcount' } if "`absorbing'" == "noabsorbing" { if "`irregular'" == "1" { ereturn scalar irregular = 1 } else { if "`aabs'" == "1" { ereturn scalar irregular = -1 } else { ereturn scalar irregular = 0 } } } if `'"`underid'"' != "" { foreach rr in j_uid df_uid p_uid j_oid df_oid p_oid { if "`r(`rr')'" != "" { cap ereturn scalar `rr' = r(`rr') } } } ** MATRICES in e() ** if "`firststage'" != "nofirststage" | "`link'" != "linear" { ereturn matrix G = `_G' } if `"`underid'"' != "" { foreach rr in b_uid V_uid S_uid b0_uid b_oid V_oid S_oid b0_oid sw_uid { cap ereturn matrix `rr' = `_`rr'' } } if "`link'" != "linear" { if "`vce'" != "opg" & "`vce'" != "oim" { ereturn matrix V_modelbased = `_Vorg_model' } ereturn matrix gradient = `_newgradient' if "`link'" != "cloglog" { ereturn matrix mns = `_newmns' ereturn matrix rules = `_rules' } } ** MACROS in e() ** ereturn local link `link' if "`link'" == "linear" { ereturn local cmd "ivregress" ereturn local estimator "2sls" } else { ereturn local cmd `link' ereturn local estimator "cf" } ereturn local cmd2 "xtdhazard" ereturn local cmdline `cmdline' if "`link'" == "linear" { ereturn local title "Own-differences IV estimation of linear discrete-time hazard model" } else { ereturn local title "Own-differences instruments CF estimation of discrete-time hazard model" } if `multidiff' != 0 { ereturn local difference "`difference'" } if "`interactinst'" == "interactinst" { ereturn local interactinst "interactions" } else if "`link'" == "linear" { ereturn local interactinst "nointeractions" } if "`weight'" != "" { ereturn local wexp "=`exp'" ereturn local wtype "`weight'" ereturn scalar wgtsum = `wmat' } if "`vce'" == "robust" | ("`weight'" == "pweight" & "`vce'" == "ols") { ereturn local vcetype "Robust" ereturn local vcest "robust" } if "`clustvar'" != "" { ereturn local vcetype "Clustered" ereturn local vcest "cluster" ereturn local clustvar "`clustvar'" ereturn scalar N_clust = round(`N_clust') } if ("`link'" != "linear") | ("`firststage'" != "nofirststage") { ereturn local endog `gnrown' ereturn local exog "`gncoln' `oinstruments'" } ereturn local instruments "" if ("`link'" != "linear") & ("`resgenerate'" != "noresgenerate") { ereturn local generated "`resnamelist'" } if ("`perfectcount'" != "" | "`e(perfect)'" != "") & (("`link'" == "linear" & "`firststage'" != "nofirststage") | ("`link'" != "linear")) { ereturn local perfect "`perfect'" } ereturn local depvar "`lhs'" ereturn local chi2type "Wald" ereturn local ivar "`ivar'" ereturn local tvar "`tvar'" if `"`underid'"' != "" { foreach rr in rkstat vceopt rkopt { if "`r(`rr')'" != "" { cap ereturn local `rr' = r(`rr') } } } } ** DISPLAY RESULTS ** _outdispxtdhazard, level(`level') `ci' `pvalues' `omitted' `vsquish' `emptycells' `baselevels' `allbaselevels' `fvdisp' cformat(`cformat') pformat(`pformat') sformat(`sformat') `lstretch' } ** REPLAY RESULTS ** else { if "`e(cmd2)'" != "xtdhazard" { error 301 } else { syntax, [LEVel(real `e(level)')] [noci] [noPValues] [noOMITted] [VSQUISH] [noEMPTYcells] [BASElevels] [ALLBASElevels] [noFVLABel] [fvwrap(integer 1)] [fvwrapon(string asis)] [CFORMAT(string asis)] /* */ [PFORMAT(string asis)] [SFORMAT(string asis)] [nolstretch] ** DISPLAY RESULTS ** _outdispxtdhazard, level(`level') `ci' `pvalues' `omitted' `vsquish' `emptycells' `baselevels' `allbaselevels' `fvdisp' cformat(`cformat') pformat(`pformat') sformat(`sformat') `lstretch' } } end ******************************************************************************** ** SUPPLEMENTARY PROGRAMS ****************************************************** ******************************************************************************** ** CALL OF UNDERID ** cap program drop callunderid program callunderid, rclass syntax [anything] if "`anything'" != "" { underid, `anything' } else { underid } return add end ** MATA FUNCTION delet_0() FOR DELETING COLUMS AND ROWS in e(b) AND e(V) REFERRING TO COLLINEAR VARS ** ** Code (mainly) borrowed from Daniel Klein (statalist 04 Jul 2016, 15:34) cap mata : mata drop delete_0() mata : void delete_0(string scalar nameb, string scalar namev, string scalar newnameb, string scalar newnamev) { real matrix __B real matrix __V string matrix cnames, rnames real rowvector __s __B = st_matrix(nameb) __V = st_matrix(namev) cnames = st_matrixcolstripe(nameb) rnames = st_matrixrowstripe(nameb) __s = (__B :!= 0) __st = __s' if (orgtype(__B) == "colvector") { rnames = select(rnames, __s) } else if (orgtype(__B) == "rowvector") { cnames = select(cnames, __st) } else { _error(3201) } st_matrix(newnameb, select(__B, __s)) st_matrixcolstripe(newnameb, cnames) st_matrixrowstripe(newnameb, rnames) st_matrix(newnamev, select(__V, __s)) st_matrix(newnamev, select(st_matrix(newnamev), __st)) st_matrixcolstripe(newnamev, cnames) st_matrixrowstripe(newnamev, cnames) } end ** DISPLAY RESULTS ** cap program drop _outdispxtdhazard program _outdispxtdhazard, nclass syntax, [LEVel(real `e(level)')] [noci] [noPValues] [noOMITted] [VSQUISH] [noEMPTYcells] [BASElevels] [ALLBASElevels] [noFVLABel] [fvwrap(integer 1)] [fvwrapon(string asis)] [CFORMAT(string asis)] [PFORMAT(string asis)] /* */ [SFORMAT(string asis)] [nolstretch] ** DISPLAY RESULTS ** local statskip = 46 local equalskip = 68 local statend = 70 local fullpara = 80 ** FV-DISPLAY OPTIONS DEPENDING ON STATA VERSION ** if `c(stata_version)' < 14 { local fvdisp "" } else { local fvdisp `"`fvlabel' fvwrap(`fvwrap') fvwrapon(`fvwrapon')"' } if "`e(wtype)'" != "" { di as text "(sum of wgt is" as text %10.7e `e(wgtsum)' as text ")" } ** DISPLAY ORDER of DIFFERENCE IN OUTPUT ** cap confirm number `e(difference)' if _rc == 0 { local r2d = `e(difference)' if `e(difference)' == 1 { local odiff `"as text "first""' local r2d "f" } if `e(difference)' == 2 { local odiff `"as result `e(difference)' as text "nd""' } if `e(difference)' == 3 { local odiff `"as result `e(difference)' as text "rd""' } if `e(difference)' >= 4 { local odiff `"as result `e(difference)' as text "th""' } } else { local odiff `"as text "multiple""' } ** DISPLAY TYPE OF MODEL ** if "`e(estimator)'" == "2sls" { local caplink "Linear" local method "IV" } else { local caplink = strproper("`e(link)'") local method "CF" } di _newline as text "`caplink' discrete-time hazard model" _continue di _column(`statskip') as text "Number of obs" _column(`equalskip') as text "=" _column(`statend') as result %9.0gc `e(N)' di as text `odiff' as text "-differences `method' estimation" _continue di _column(`statskip') as text "Number of groups" _column(`equalskip') as text "=" _column(`statend') as result %9.0gc `e(N_g)' if "`e(irregular)'" == "1" { di as text "`e(depvar)' inconsistent with hazard model" _continue } if "`e(irregular)'" == "-1" { di as text "obs. after abs. state reached considered" _continue } di _column(`statskip') as text "Wald chi2(" as result %1.0f `e(df_m)' as text ")" _column(`equalskip') as text "=" _column(`statend') as result %9.2f `e(chi2)' di _column(`statskip') as text "Prob > chi2" _column(`equalskip') as text "=" _column(`statend') as result %9.3f `e(p)' if "`e(estimator)'" == "2sls" { di _column(`statskip') as text "R-sq" _column(`equalskip') as text "=" _column(`statend') as result %9.3f `e(r2)' _newline } else { di as text "Log pseudolikelihood = " as result %9.3f `e(ll)' } ereturn display, level(`level') `ci' `pvalues' `omitted' `vsquish' `emptycells' `baselevels' `allbaselevels' `fvdisp' cformat(`cformat') pformat(`pformat') sformat(`sformat') `lstretch' if "`e(interactinst)'" == "interactions" { di in smcl as text "{p 0 6 0 `fullpara'}Squares and cross-products of instruments included in first-stage regressions{p_end}" } ** REPORT RESULT FROM UNDERIDENTIFICATION TEST ** if ("`e(df_uid)'" != "" ) & ("`disptest'" != "noisily") { di as text "Underidentification test: " as text "j = " as result %9.2f `e(j_uid)' as text "; Chi-sq(" as result %4.0g `e(df_uid)' as text "); p-value = " as result %5.4f `e(p_uid)' /*_newline*/ } if ("`e(df_oid)'" != "" ) & ("`disptest'" != "noisily") { di as text "Overidentification test: " as text "j = " as result %9.2f `e(j_oid)' as text "; Chi-sq(" as result %4.0g `e(df_oid)' as text "); p-value = " as result %5.4f `e(p_oid)' /*_newline*/ } if "`e(k_perfect)'" != "" { if `e(k_perfect)' > 0 { if `e(k_perfect)' > 1 { local plural "s" } if "`e(link)'" != "linear" { di in smcl as result "{p 0 6 0 `fullpara'}`e(k_perfect)'" as text " first-stage residual`plural' collinear, dropped from second stage: " as result "`e(perfect)'{p_end}" } else { di in smcl as result "{p 0 6 0 `fullpara'}`e(k_perfect)'" as text " rhs variable`plural' perfectly predicted in first-stage regression: " as result "`e(perfect)'{p_end}" } } } end