Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Coding the tobit log-likelihood in Stata

    (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?

    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

  • #2
    You didn't get a quick answer. This probably reflects two things. First, with Tobit programmed, it is not clear why you'd bother programming it yourself. Even though you may drop some stuff, you won't necessarily be more efficient than the Stata routine. Second, it is exceedingly difficult to look at someone's code and diagnose a problem.

    One problem, you have a program called mytobit_lc which you later refer to as mytobit_ll.

    Comment


    • #3
      Thanks, Phil. I am just trying to learn how it works. I don't think that is so crazy. There are practical applications, too. For example, what if you wanted to add an inequality constraint to a Tobit model?

      Edit: On another post your tell the author:

      You'll increase your chances of a helpful answer if you follow the FAQ on asking questions - provide Stata code in code delimiters, Stata output, and sample data.
      Which is exactly what I've done here. Moreover, this is a purely Stata question: how to code the Tobit log-likelihood for right-constrained and two-limit problems.


      Last edited by Jack Serck; 10 Jul 2017, 13:51.

      Comment

      Working...
      X