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

  • Hand Calculations of Marginal Effects: Adjusted Predictions at Representative values (APR)

    Hi All,
    // Stata-MP 14.2 - (user-written commands not possible)
    // Large, "very short" (N>>T) longitudinal data of firm employment and payroll

    I'm well familiar with the -margins- command and the available resources, but still haven't been able to recreate the margins results based on adding up the coefficients. I've looked into the very helpful, which provides example for the APM, MEM and AME but not for APR.
    Similarly, the Stata videos by Chuck Huber also show hand calculations but not for this type.

    size: categorical variable
    growth: discrete variable

    xtreg payroll c.growth##i.size if growth>0
    margins i.size, at(growth=(.1 .5 1))
    To replicate growth of .1 at size 2 I tried to alter the examples given by the aforementioned resources

    but despite numerous variations, to no avail. Does someone know how APR margins are calculated?

    Last edited by Jeff Thompson; 17 May 2018, 15:11.

  • #2
    Hi Jeff,
    I suspect that you do not get the same result as -marging- because you are not multiplying your interaction term _b[2.size#growth] by .1

    Your code should thus be
    _b[growth]*.1+_b[2.size]+_b[2.size#growth]*.1+_b[_cons] if e(sample)
    I've also added -if e(sample)-, this is important if you have other control variables.

    Here an example that mirrors you case:
    webuse nlswork, clear
    xtset idcode year
    qui xtreg ln_wage i.race##c.hours if hours>20
    margins race, at(hour=(40))
    Adjusted predictions                            Number of obs     =     25,393
    Model VCE    : Conventional
    Expression   : Linear prediction, predict()
    at           : hours           =          40
                 |            Delta-method
                 |     Margin   Std. Err.      z    P>|z|     [95% Conf. Interval]
            race |
          white  |   1.705663   .0072225   236.16   0.000     1.691508    1.719819
          black  |   1.562293   .0113957   137.09   0.000     1.539958    1.584628
          other  |   1.772997   .0575848    30.79   0.000     1.660133    1.885861
    . gen pw = _b[_cons]+_b[2.race]+_b[hours]*40+_b[2.race#hours]*40 if e(sample)
    (3,141 missing values generated)
    . sum pw
        Variable |        Obs        Mean    Std. Dev.       Min        Max
              pw |     25,393    1.562293           0   1.562293   1.562293
    sum pw



    • #3
      Spot on! Yeah this worked. However adding a second categorical variable messes things up:

      age: values 1, 2, or 3

      xtreg payroll c.growth##i.size i.age if growth>0, re vce(cluster id)
      margins i.size, at(growth=(.1 .5 1))
      Do you know how it would be calculated here? I thought the e(sample) would have sorted this out but not really sure what it's function plays.

      *Note: added ,re vce(cluster id)


      • #4
        If you add a further variable you have to take it into account also in your by-hand-calculation.
        Following on the previous example I add the var "collgrad"

        xtreg ln_wage i.race##c.hours i.collgrad if hours>20, re vce(cluster idcode)
        margins race, at(hour=(40))
        gen pw = _b[_cons]+_b[2.race]+_b[hours]*40+_b[2.race#hours]*40+_b[1.collgrad]*collgrad if e(sample)
        sum pw

        Note that you were already estimating a -re-, which is the default.
        Also, the -vce(cluster id)- only affects standard errors.


        • #5

          Alright thanks! I tried this but didn't get them to add up. I may have to do with that _b[1.collgrad] is 0 because all other collgrad categories are in reference to it.

          Sorry but I can't post the output due to copy/paste network restrictions all I have are the screenshots.

           xtreg payroll c.growth##i.size i.age if growth>0, re vce(cluster id)
          Click image for larger version

Name:	Screen Shot 2018-05-19 at 3.48.57 PM.png
Views:	1
Size:	153.6 KB
ID:	1444878

          margins i.size, at(growth=(.25 .5))

          Click image for larger version

Name:	Screen Shot 2018-05-19 at 3.58.13 PM.png
Views:	1
Size:	129.8 KB
ID:	1444881

          Click image for larger version

Name:	Screen Shot 2018-05-19 at 3.58.34 PM.png
Views:	1
Size:	110.2 KB
ID:	1444880

          The red box is the number I'm trying to recalculate by hand. gen s is where I tried your code. gen s2 is where I tried finding the mean of all of the coefficients for age and this got the number closer. However, it's not the same and I'm still not sure if it's just a coincidence. Do you have any idea why this could be?