Announcement

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

  • oprobit with marginal effects- mfx alternative

    I am replicating an older paper which uses oprobit followed by mfx to calculate and report marginal effects of sex (0-male 1-female) on level of education (1-5)

    I am able to replicate the marginal effects in the paper by using the following code

    Code:
    levelsof year, local(year)
    foreach r of local year{
        eststo: oprobit edu_level sex if  year==`r' [pw=wt], vce(robust)
    
    mfx, predict(pr outcome(1))
    mfx, predict(pr outcome(2))
    mfx, predict(pr outcome(3))
    mfx, predict(pr outcome(4))
    mfx, predict(pr outcome(5))    
    }
    However, I have 2 issues.

    1. I want to avoid using mfx and instead use margins
    2. I want Stata to automatically store my marginal effects in a word/csv file.

    For that I am using the following command

    Code:
    levelsof year, local(year)
    foreach r of local year{
        eststo: oprobit edu_level sex if  year==`r' [pw=wt], vce(robust)
    
     margins, dydx (*) predict(pr outcome(1)) post
     margins, dydx (*) predict(pr outcome(2)) post
     margins, dydx (*) predict(pr outcome(3)) post
     margins, dydx (*) predict(pr outcome(4)) post
     margins, dydx (*) predict(pr outcome(5)) post   
    
    esttab using eduprobit.csv, se r2 b(4) se(4) star(* 0.10 ** 0.05 *** 0.01)
    }
    However, in this case my marginal effects are coming out slightly different that when i used the mfx command. Where am I going wrong?

    And the CSV file reports the oprobit results but doesn't store the 5 marginal effects I am hoping to use. How do I fix that? I read on another forum that using 'post' at the end of the margin command should fix it. But that doesn't seem to be working for me.

    I appreciate the help!

  • #2
    You probably need to add the -atmeans- option to margins.

    After each margins command you probably need something like

    est store m1
    -------------------------------------------
    Richard Williams, Notre Dame Dept of Sociology
    StataNow Version: 19.5 MP (2 processor)

    EMAIL: [email protected]
    WWW: https://www3.nd.edu/~rwilliam

    Comment


    • #3
      The atmeans option makes the result even more different from the 'mfx' result. Using the margins command is consistently producing smaller absolute marginal effects. Is there some particular reason why that may be happening?

      Also it seems using est store and post together with margins is producing an error. I get a message saying

      Code:
      qui oprobit y xi
      margins dydx (*) predict (pr outcome(1)) post 
      <result>
      est sto m1
      margins, dydx predict(pr outcome(2)) post
      option dydx not allowed

      Comment


      • #4
        i have a feeling you aren't showing exactly what you typed. In your last example you need a comma after margins and before dydx. Having posted the margins result your second margins command won't have the probit results to work with. I suggest you copy and paste your results for both mfx and margins, at least for outcome 1, so we can see exactly what you are doing.
        -------------------------------------------
        Richard Williams, Notre Dame Dept of Sociology
        StataNow Version: 19.5 MP (2 processor)

        EMAIL: [email protected]
        WWW: https://www3.nd.edu/~rwilliam

        Comment


        • #5
          Sorry. I am going to copy my output directly from Stata. Here's the result with one round of data and using mfx

          Code:
          qui oprobit genedu sex if round==2000 [pw=wt], vce(robust)
          
          . mfx, predict(pr outcome(1))
          
          Marginal effects after oprobit
                y  = Pr(genedu==1) (predict, pr outcome(1))
                   =  .36653796
          ------------------------------------------------------------------------------
          variable |      dy/dx    Std. Err.     z    P>|z|  [    95% C.I.   ]      X
          ---------+--------------------------------------------------------------------
             sex*|   .2086664      .00328   63.69   0.000   .202245  .215088   .293946
          ------------------------------------------------------------------------------
          (*) dy/dx is for discrete change of dummy variable from 0 to 1
          
          . mfx, predict(pr outcome(2))
          
          Marginal effects after oprobit
                y  = Pr(genedu==2) (predict, pr outcome(2))
                   =  .11578866
          ------------------------------------------------------------------------------
          variable |      dy/dx    Std. Err.     z    P>|z|  [    95% C.I.   ]      X
          ---------+--------------------------------------------------------------------
             sex*|    .004935      .00027   18.33   0.000   .004407  .005463   .293946
          ------------------------------------------------------------------------------
          (*) dy/dx is for discrete change of dummy variable from 0 to 1
          . 
          . mfx, predict(pr outcome(3))
          
          Marginal effects after oprobit
                y  = Pr(genedu==3) (predict, pr outcome(3))
                   =  .14403116
          ------------------------------------------------------------------------------
          variable |      dy/dx    Std. Err.     z    P>|z|  [    95% C.I.   ]      X
          ---------+--------------------------------------------------------------------
             sex*|    -.01833      .00051  -35.80   0.000  -.019334 -.017326   .293946
          ------------------------------------------------------------------------------
          (*) dy/dx is for discrete change of dummy variable from 0 to 1
          
          . mfx, predict(pr outcome(4))
          
          Marginal effects after oprobit
                y  = Pr(genedu==4) (predict, pr outcome(4))
                   =   .1630264
          ------------------------------------------------------------------------------
          variable |      dy/dx    Std. Err.     z    P>|z|  [    95% C.I.   ]      X
          ---------+--------------------------------------------------------------------
             sex*|  -.0531314        .001  -53.40   0.000  -.055082 -.051181   .293946
          ------------------------------------------------------------------------------
          (*) dy/dx is for discrete change of dummy variable from 0 to 1
          
          . mfx, predict(pr outcome(5))
          
          Marginal effects after oprobit
                y  = Pr(genedu==5) (predict, pr outcome(5))
                   =  .21061582
          ------------------------------------------------------------------------------
          variable |      dy/dx    Std. Err.     z    P>|z|  [    95% C.I.   ]      X
          ---------+--------------------------------------------------------------------
             sex*|  -.1421401      .00206  -68.99   0.000  -.146178 -.138102   .293946
          ------------------------------------------------------------------------------
          (*) dy/dx is for discrete change of dummy variable from 0 to 1

          This is the result with margins command- notice how the marginal effects are different from the above using mfx?
          I want to not have to run the oprobit after storing every marginal effects.


          Code:
          qui oprobit genedu sex if round==2000 [pw=wt], vce(robust)
          eststo m1: margins, dydx (sex) pr (outcome (1)) post
          
          Average marginal effects                          Number of obs   =     190843
          Model VCE    : Robust
          
          Expression   : Pr(genedu==1), predict(outcome (1))
          dy/dx w.r.t. : sex
          
          ------------------------------------------------------------------------------
                       |            Delta-method
                       |      dy/dx   Std. Err.      z    P>|z|     [95% Conf. Interval]
          -------------+----------------------------------------------------------------
                 sex|   .1986286   .0029323    67.74   0.000     .1928813    .2043759
          ------------------------------------------------------------------------------
          
          . eststo m2: margins, dydx (sex) pr (outcome (2)) post
          option dydx() not allowed
          r(198);

          Instead of running oprobit after every marginal effect at each of the five outcomes- Is there some way to run the oprobit once- get all the 5 marginal effects and then export them to word/csv all together?

          Comment


          • #6
            On the observed differences, use factor variable notation (help fvvarlist) with margins. Otherwise sex is interpreted as continuous. Code

            Code:
            oprobit genedu i.sex if round==2000 [pw=wt] ,vce(robust)
            and your results will match.

            Best
            Daniel
            Last edited by daniel klein; 12 Mar 2015, 09:01.

            Comment


            • #7
              I want to not have to run the oprobit after storing every marginal effects.
              On this one, also I have not followed closely why you need the post option, here is a sketch

              Code:
              oprobit ...
              
              forv j = 1/5 {
                  _estimates hold myeresults ,copy
                  eststo m`j' : margins ,dydx(sex) pr(outcome(2)) post
                  _estimates unhold myresults
              }
              Best
              Daniel

              Comment


              • #8
                Daniel is right about the factor variable notation. Note that, for mfx, I think the oprobit needs to just use sex, but for margins you will need to say i.sex. Otherwise I think mfx will choke on the factor variables.

                In addition, your margins command is not using the -atmeans- option. Like I said before, this is necessary to make it comparable to mfx.

                In short, part of your code should look something like

                Code:
                qui oprobit genedu sex if round==2000 [pw=wt], vce(robust)
                mfx, predict(pr outcome(1))
                qui oprobit genedu i.sex if round==2000 [pw=wt], vce(robust)
                margins, dydx(sex) pr(outcome (1)) atmeans post
                If mfx and margins are giving different results with the above code let us know. I can't remember if mfx works correctly with weighted data or not.
                -------------------------------------------
                Richard Williams, Notre Dame Dept of Sociology
                StataNow Version: 19.5 MP (2 processor)

                EMAIL: [email protected]
                WWW: https://www3.nd.edu/~rwilliam

                Comment


                • #9
                  Thanks!!

                  That seems to have fixed it.

                  I am using this code and it's producing results almost exactly the same as the paper

                  Code:
                  foreach r of local round {
                      qui oprobit genedu i.sex if  round==`r' [pw=hhwt], vce(robust)
                      eststo oprobit
                          foreach o in 1 2 3 4 5 {
                              quietly margins, dydx(*) pr (outcome(`o')) post atmeans
                              eststo, title(Outcome `o')
                              estimates restore oprobit
                          }
                      eststo drop oprobit
                      esttab using probit.csv, se nostar mtitles nonumbers nobase title(Average Marginal Effects Education `r') append obslast
                   }
                  Quick follow-up questions. If I want to test whether there has been a significant change in the marginal effect for outcome 1 between round 1 and 3 or between round 2 and 5 etc. How would I go about doing that? A simple t-test would suffice- but I am struggling with the code.

                  I appreciate the help!

                  Comment

                  Working...
                  X