Announcement

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

  • Failing to replicate margins example 16: Average marginal effect (partial effects)

    This is the code for margins Example 16

    Code:
    use https://www.stata-press.com/data/r17/margex
    quietly logistic outcome treatment##group age c.age#c.age treatment#c.age
    margins, dydx(treatment)
    which gives a marginal effect for treatment of 0.0385625.

    I have tried to manually calculate this marginal effect using the following code.
    First I take the average prediction, in log-odds scale, with treatment=1. Then I take the average prediction, in log-odds scale, with treatment=0.
    Then I subtract the latter from the former.
    Then I convert log-odds in odds and then in probabilities.

    But the result is nowhere near what I obtain with margins.

    What am I doing wrong?
    Code:
    quietly capture drop yhat
    quietly capture drop treatment_bk
    quietly gen treatment_bk = treatment
    quietly replace treatment = 1
    quietly predict yhat, xb
    quietly sum yhat
    global lo1 = r(mean)
    quietly capture drop yhat
    quietly replace treatment = 0
    quietly predict yhat, xb
    quietly sum yhat
    global lo0 = r(mean)
    quietly capture drop yhat
    global mar = (${lo1} - ${lo0})
    disp exp(${mar})/(1+exp(${mar}))
    quietly capture drop treatment
    quietly capture drop yhat
    quietly rename treatment_bk treatment
    EDIT: fix code
    Last edited by Giuseppe Polito; 03 Sep 2022, 19:10.

  • #2
    You are getting wrong results because the invlogit() function is non-linear, so invlogit(mean()) != mean(invlogit()). You have calculated the mean values of xb with treatment replaced by 0 and 1. And then you applied the invlogit function to those means. But that is not what -margins- does. -margins- applies the invlogit() function to the values of xb first (producing predicted probabilities) and then takes the mean.

    Here's how it works:

    Code:
    use https://www.stata-press.com/data/r17/margex, clear
    quietly logistic outcome treatment##group age c.age#c.age treatment#c.age
    margins treatment
    margins, dydx(treatment)
    
    gen treatment_bak = treatment
    
    forvalues i = 0/1 {
        replace treatment = `i'
        predict yhat`i', pr
        summ yhat`i'
    }
    Last edited by Clyde Schechter; 03 Sep 2022, 18:55. Reason: Correct references to invlogit() function.

    Comment


    • #3
      Perhaps - I'm not sure - the following will explain the problem.

      In the output of
      Code:
      help margins
      click on
      Code:
      (View complete PDF manual entry)
      at the top of the output. This will open the Stata Stata Base Reference Manual PDF included in your Stata installation to the full documentation for the margins command. Scroll down to

      Obtaining margins of derivatives of responses (a.k.a. marginal effects)
      and within that section scroll further to

      Derivatives versus discrete differences
      There you will find a discussion that includes

      margins calculates dydx() differently for continuous and for factor variables.
      and elaborates further on the differences. I hope that in that explanation you will see the source of the difference.

      Comment


      • #4
        Originally posted by Clyde Schechter View Post
        You are getting wrong results because the invlogit() function is non-linear, so invlogit(mean()) != mean(invlogit()). You have calculated the mean values of xb with treatment replaced by 0 and 1. And then you applied the invlogit function to those means. But that is not what -margins- does. -margins- applies the invlogit() function to the values of xb first (producing predicted probabilities) and then takes the mean.

        Here's how it works:

        Code:
        use https://www.stata-press.com/data/r17/margex, clear
        quietly logistic outcome treatment##group age c.age#c.age treatment#c.age
        margins treatment
        margins, dydx(treatment)
        
        gen treatment_bak = treatment
        
        forvalues i = 0/1 {
        replace treatment = `i'
        predict yhat`i', pr
        summ yhat`i'
        }
        Thank you very much! That works and it is clear now

        @William Lisowski you are probably referring to an old version of my post where I computed derivatives instead of discrete changes. I'm sorry for that

        Comment

        Working...
        X