*! version 1.0.1 07nov2001 program define intreg2, eclass byable(recall) version 7 if replay() { if `"`e(cmd)'"'!="intreg2" { error 301 } if _by() { error 190 } DiIntreg `0' /* display results */ error `e(rc)' exit } /* Parse and check options. */ syntax varlist(min=2 numeric) [aw fw pw iw] [if] [in] /* */ [, Het(varlist) From(string) Level(integer $S_level) /* */ noLOg noCONstant Robust CLuster(varname) SCore(string) /* */ noDISPLAY * ] /* -offset()- is deleted, use -constraint()- instead */ if _by() { _byoptnotallowed score() `"`score'"' } mlopts mlopts, `options' if `level' < 10 | `level' > 99 { di in red "level() must be between 10 and 99" exit 198 } gettoken y1 rhs : varlist gettoken y2 rhs : rhs if "`constant'"!="" & "`rhs'"=="" { di in red /* */ "independent variables required with noconstant option" exit 100 } if "`weight'"!="" { if "`weight'"!="fweight" { local wt "aweight" } else local wt "fweight" } if "`cluster'"!="" { local clopt cluster(`cluster') } if `"`score'"'!="" { confirm new variable `score' local nword : word count `score' if `nword' != 2 { di in red "score() must contain the names of " /* */ "two new variables" exit 198 } tempvar s1 s2 local scopt score(`s1' `s2') } /* Mark/markout. */ tempvar doit z mark `doit' [`weight'`exp'] `if' `in' qui replace `doit' = 0 if `y1'==. & `y2'==. /* Check that `y1'<=`y2' and markout independent variables. */ capture assert `y1'<=`y2' if `y1'!=. & `y2'!=. & `doit' if _rc { di in red `"observations with `y1' > `y2' not allowed"' exit 498 } markout `doit' `rhs' `offset' if "`cluster'"!="" { markout `doit' `cluster', strok } /* Count number of observations (and issue error 2000 if necessary). */ _nobs `doit' [`weight'`exp'] local N `r(N)' _nobs `doit' [`weight'`exp'] if `y1'==`y2', min(0) local Nunc `r(N)' _nobs `doit' [`weight'`exp'] if `y1'==., min(0) local Nlc `r(N)' _nobs `doit' [`weight'`exp'] if `y2'==., min(0) local Nrc `r(N)' /* Remove collinearity. */ if "`y1'" == "`y2'" { _rmdcoll `y1' `rhs' [`weight' `exp'] if `doit', `constant' local rhs `r(varlist)' } else { cap _rmdcoll `y1' `rhs' [`weight' `exp'] if `doit', `constant' if _rc != 0 { cap _rmdcoll `y2' `rhs' [`weight' `exp'] if `doit', `constant' } if _rc != 0 { dis in red /* */ "`y1' and `y2' collinear with independent variables" exit 459 } local rhs `r(varlist)' } /* Fit homoskedastici model, get starting values */ if "`from'"!="" { local start "init(`from', copy)" } else { qui intreg `y1' `y2' `rhs' [`weight'`exp'] if `doit', /* */ `constant' tempname b0 b00 b_start tempvar sigma_con mat `b0'=e(b) local matlen=colsof(`b0')-1 mat `b00'=`b0'[1,1..`matlen'] qui gen `sigma_con'=ln(`b0'[1,colsof(`b0')]) qui reg `sigma_con' `het' [`wt'`exp'] if `doit' mat `b_start'=(`b00', e(b)) local start "init(`b_start', copy)" } /* Fit heteroskedastic model. */ ml model d2 intrg_v_ll (model: `y1' `y2'=`rhs', `constant') /* */ (lnsigma: `het') [`weight'`exp'] if `doit', /* */ `initopt' `mlopts' `robust' `clopt' `start' /* */ `scopt' `contin' `log' noout missing collinear nopreserve /* */ obs(`N') maximize search(off) est local cmd global S_E_cmd est scalar N_unc = `Nunc' est scalar N_lc = `Nlc' est scalar N_rc = `Nrc' est scalar N_int = e(N) - e(N_unc) - e(N_lc) - e(N_rc) if "$S_BADLC"!="" { est scalar N_lcout = $S_BADLC /* # outlier intervals approximated as LC */ global S_BADLC } if "$S_BADRC"!="" { est scalar N_rcout = $S_BADRC /* # outlier intervals approximated as RC */ global S_BADRC } est local title "Interval regression" est local depvar `y1' `y2' est local predict "intreg2_p" /* Double save in S_E_. */ global S_E_nobs `e(N)' global S_E_depv `e(depvar)' global S_E_ll `e(ll)' global S_E_chi2 `e(chi2)' global S_E_mdf `e(df_m)' if `"`score'"'!=`""' { label var `s1' "intreg score for x*b" label var `s2' "intreg score for /sigma" local name : word 1 of `score' rename `s1' `name' local name : word 2 of `score' rename `s2' `name' } est local cmd "intreg2" est local hetvar "`het'" global S_E_cmd `e(cmd)' /* Display results. */ if "`display'" == "" { DiIntreg, level(`level') error `e(rc)' } end program define DiIntreg syntax [, Level(integer $S_level) ] if `level' < 10 | `level' > 99 { di in red "level() must be between 10 and 99" exit 198 } if "`e(hetvar)'" ~= "" { ml display, level(`level') } else { ml display, level(`level') first plus _diparm lnsigma, level(`level') noprob _diparm lnsigma, level(`level') exp label("sigma") di as text "{hline 13}" _col(14) `"{c BT}"' "{hline 64}" } /* Note: Wald test for sigma on boundary -- not reported. */ censobs_table e(N_unc) e(N_lc) e(N_rc) e(N_int) if e(N_lcout)==. & e(N_rcout)==. { exit } /* The following messages should be VERY rare. */ if e(N_lcout) == 1 { di _n in blu "note: 1 interval observation was an " /* */ "extreme outlier (large negative residual)" _n /* */ " and was handled by assuming it was a " /* */ "left-censored observation." } else if e(N_lcout) != . { di _n in blu "note: `e(N_lcout)' interval observations " /* */ "were extreme outliers (all with large negative" _n /* */ " residuals) and were handled by " /* */ "assuming they were left-censored observations." } if e(N_rcout) == 1 { di _n in blu "note: 1 interval observation was an " /* */ "extreme outlier (large positive residual)" _n /* */ " and was handled by assuming it was a " /* */ "right-censored observation." } else if e(N_rcout) != . { di _n in blu "note: `e(N_rcout)' interval observations " /* */ "were extreme outliers (all with large positive" _n /* */ " residuals) and were handled by " /* */ "assuming they were right-censored observations." } di in blu /* */ " This is an excellent approximation for all intervals " /* */ "except for those" _n " that are very narrow." end