(Note: cross-post from Stack Overflow. Didn't get any bites.)
I am trying to roll tobit models by hand in Stata. So far I can replicate the output from the built-in routine tobit when setting a lower limit (ll(#)). However, my results are different when I set an upper limit (ul(#)) or both. Unfortunately I can't tell if it is because I am making a Stata programming error, or because I am entering the log-likelihood functions incorrectly.
Here is an example using the foreign data set with a fake predictor censored at 0 and 1. Canned routines (tobit) are models "m1_[n]"; custom routines are models "m2_[n]". I run models for lower limits (n=1), upper limits (n=2) and two-limits (n=3).
Is my syntax for the upper limit and two-limit models correct? If not, what am I missing?
I am trying to roll tobit models by hand in Stata. So far I can replicate the output from the built-in routine tobit when setting a lower limit (ll(#)). However, my results are different when I set an upper limit (ul(#)) or both. Unfortunately I can't tell if it is because I am making a Stata programming error, or because I am entering the log-likelihood functions incorrectly.
Here is an example using the foreign data set with a fake predictor censored at 0 and 1. Canned routines (tobit) are models "m1_[n]"; custom routines are models "m2_[n]". I run models for lower limits (n=1), upper limits (n=2) and two-limits (n=3).
Is my syntax for the upper limit and two-limit models correct? If not, what am I missing?
Code:
// BEGIN sysuse auto, clear version 13 set more off // generate fake data: lower limit is zero, upper limit is one gen y =invnormal(runiform()) replace y = 0 if y < 0 replace y = 1 if y > 1 // 1.1 canned tobit, left-censored qui tobit y length turn headroom, ll(0) eststo m1_1 // 1.2 user tobit, left-censored capture program drop mytobit_ll program mytobit_lc args lnf beta sigma tempvar lnlj quietly { gen double `lnlj' = log(1-normal(`beta'/`sigma')) if $ML_y1==0 replace `lnlj' = log((1/`sigma')*normalden(($ML_y1-`beta')/`sigma')) if $ML_y1>0 replace `lnf' = `lnlj' } end ml model lf mytobit_ll (y = length turn headroom) /sigma qui ml maximize, nolog eststo m1_2 // 2.1 canned tobit, right-censored qui tobit y length turn headroom, ul(1) eststo m2_1 // 2.2 user tobit, right-censored capture program drop mytobit_ul program mytobit_ul args lnf beta sigma tempvar lnlj quietly { gen double `lnlj'= log(1-normal((`beta')/`sigma')) if $ML_y1==1 replace `lnlj'= log((1/`sigma')*normalden(($ML_y1-`beta')/`sigma')) if $ML_y1<1 replace `lnf' = `lnlj' } end ml model lf mytobit_ul (y = length turn headroom) /sigma qui ml maximize, nolog eststo m2_2 // 3.1 canned tobit, left-censored and right-censored qui tobit y length turn headroom, ll(0) ul(1) eststo m3_1 // 3.2 user tobit, left-censored and right-censored capture program drop mytobit_twolimit program mytobit_twolimit args lnf beta sigma tempvar lnlj quietly { gen double `lnlj'= log(1-normal(`beta'/`sigma')) if $ML_y1==0 // lower limit replace `lnlj'= log(normal(`beta'/`sigma')) if $ML_y1==1 // upper limit replace `lnlj'= log((1/`sigma')*normalden(($ML_y1-`beta')/`sigma')) if $ML_y1>0 | $ML_y1<1 // uncensored replace `lnf' = `lnlj' } end ml model lf mytobit_twolimit (y = length turn headroom) /sigma qui ml maximize, nolog eststo m3_2 // results esttab m1_1 m1_2 m2_1 m2_2 m3_1 m3_2, mtitles("canned LC" "user LC" "canned RC" "user RC" "canned 2L" "user 2L") // END
Comment