Announcement

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

  • marginsplot spacing issue

    This is my first post on the forum. Thanks in advance for any response. I am using marginsplot in Stata 16.1 to plot average marginal effects of six predictor variables from a partial proportional odds model regressing ordinal well-being outcomes (using the user-written gologit2 from SSC, version 3.2.5). My question is: with marginsplot, how can I make the estimates plotted have equal horizontal spacing between them? For the purpose of exploration, I have generated 20 different graphs using marginsplots from this model. This is the only marginsplot where this unequal horizontal spacing is present, and I cannot find what I'm doing differently/wrong to create this problem.

    This is my actual graph, on which I have drawn arrows and hollow marker symbols towards the right, pointing to the correction I hope to make (moving the markers for logincome's MEs to the right so they are over their tick and as far away from their left side neighbor as the others are to theirs.
    Click image for larger version

Name:	actual-demo.png
Views:	1
Size:	233.9 KB
ID:	1613533


    Here is the code I ran to get the average marginal effects of these six predictors:

    Code:
    //earlier
    gologit2 INDEX_LER i.Prosocial i.freedom i.counton i.healthprob ///
    i.education i.corruptind c.logincome c.logage i.gender i.region i.hindu ///
    i.decade if year==2009, ///
    vce(robust) autofit gamma
    estimates store ppo2009
    //and now
    estimates restore ppo2009
    margins, dydx(Prosocial freedom counton healthprob corruptind logincome)
    Then I have marginsplot code, formatted the way I want it except for the spacing between the last two estimates. The following abbreviated code reproduces the problem (when working with my full data set, anyway):

    Code:
    /*this abbreviated code also generates the problem I am trying to figure out; please note spacing
    between 10 and 11 on x axis, and how 2 4 6 8 10 are evenly spaced, but not 10 and 11 */
    marginsplot, noci allsimplelabels nolabel
    This is what my abbreviated marginsplot code produces, which is the same problem without the formatting code in place. Hence, I'm unsure what the source of my problem is, why the MEs for logincome are not evenly spaced like the others are, nor how to fix it. I know the problem is something I have done wrong or omitted. If anyone knows what it is, I thank you in advance for your time.
    Click image for larger version

Name:	simplified-demo.png
Views:	1
Size:	193.3 KB
ID:	1613534




    This is a sample of my data:
    Code:
    * Example generated by -dataex-. For more info, type help dataex
    clear
    input byte(gender education) int year byte(counton region) float(logincome logage) byte(hindu freedom healthprob corruptind) int decade byte(Prosocial INDEX_LER _est_ppo2009)
    1 1 2009 1 5  3.196875  1.612784 1 1 0 1 2009 0 . 0
    0 1 2009 1 2  3.418724   1.39794 1 0 1 1 2009 0 2 1
    0 1 2009 0 5  3.321814   1.39794 1 1 0 1 2009 1 1 1
    1 2 2009 0 4  3.719754  1.612784 1 1 0 1 2009 1 2 1
    1 2 2009 0 4  3.497905   1.20412 1 0 0 1 2009 1 2 1
    0 1 2009 1 4  4.321814   1.69897 0 1 0 1 2009 1 . 0
    1 1 2009 1 3  3.418724  1.544068 1 0 0 1 2009 1 2 1
    0 1 2009 0 4  3.497905 1.5797836 1 1 0 1 2009 0 2 1
    0 2 2009 1 3  4.196875  1.544068 1 1 0 1 2009 0 2 1
    1 2 2009 1 2  3.798935 1.3424227 1 0 0 0 2009 0 2 1
    1 1 2009 1 5  3.798935 1.6812413 1 0 0 1 2009 0 2 1
    0 1 2009 1 5  3.418724   1.39794 1 0 0 1 2009 1 2 1
    1 1 2009 1 5  3.622844   1.30103 1 1 0 1 2009 1 2 1
    1 1 2009 0 4  4.020784   1.69897 0 0 0 1 2009 1 2 1
    1 2 2009 0 4  4.020784 1.6532125 0 1 0 1 2009 0 2 1
    1 2 2009 1 3  3.321814 1.2787536 1 1 0 1 2009 1 . 0
    1 1 2009 0 1  3.622844  1.518514 1 1 1 1 2009 0 . 0
    1 2 2009 1 5  3.798935   1.50515 1 0 0 1 2009 1 2 1
    1 1 2009 1 5  3.497905 1.6532125 1 1 0 1 2009 0 2 1
    1 1 2009 1 2 3.6739964 1.6532125 0 0 0 1 2009 0 2 1
    end
    label values gender gender
    label def gender 0 "female", modify
    label def gender 1 "male", modify
    label values education education
    label def education 1 "up to 8 years basic", modify
    label def education 2 "9-15 years", modify
    label values counton counton
    label def counton 0 "no social support", modify
    label def counton 1 "yes social support", modify
    label values region region
    label def region 1 "Central", modify
    label def region 2 "East", modify
    label def region 3 "West", modify
    label def region 4 "North", modify
    label def region 5 "South", modify
    label values hindu hindu
    label def hindu 0 "not Hindu", modify
    label def hindu 1 "Hindu", modify
    label values freedom freedom
    label def freedom 0 "no freedom", modify
    label def freedom 1 "yes freedom", modify
    label values healthprob healthprob
    label def healthprob 0 "no health prob", modify
    label def healthprob 1 "yes health prob", modify
    label values corruptind corruptind
    label def corruptind 0 "no corruption", modify
    label def corruptind 1 "yes corruption", modify
    label values decade decade
    label values Prosocial Prosocial
    label def Prosocial 0 "no prosocial", modify
    label def Prosocial 1 "yes prosocial", modify
    label values INDEX_LER INDEX_LER
    label def INDEX_LER 1 "Suffering", modify
    label def INDEX_LER 2 "Struggling", modify
    label var gender "gender" 
    label var education "education level" 
    label var year "year" 
    label var counton "someone to count on" 
    label var region "Region" 
    label var logincome "log-10 income" 
    label var logage "log-10 age" 
    label var hindu "Hindu" 
    label var freedom "freedom - life choices" 
    label var healthprob "major health problems" 
    label var corruptind "perceived corruption" 
    label var decade "2009 or 2019" 
    label var Prosocial "Prosociality Index" 
    label var INDEX_LER "Life Evaluation Index" 
    label var _est_ppo2009 "esample() from estimates store"
    I am using Stata SE 16.1.

  • #2
    gologit2 is from SSC (FAQ Advice #12). As you are mixing categorical variables and a continuous variable, the former (all vars except log income) have base categories while the latter does not. Perhaps there is an option in marginsplot to exclude the base categories, but this is not apparent to me. Some possibilities include extracting the margins and using twoway to create the margins plot, but here I show how you can use coefplot from SSC to create the margins plot.

    Code:
    ssc install coefplot, replace
    Some additional observations are needed to make your data example reproducible.

    Code:
    * Example generated by -dataex-. For more info, type help dataex
    clear
    input byte(gender education) int year byte(counton region) float(logincome logage) byte(hindu freedom healthprob corruptind) int decade byte(Prosocial INDEX_LER _est_ppo2009 new)
    1 1 2009 1 5  3.196875  1.612784 1 1 0 1 2009 0 . 0 0
    0 1 2009 1 2  3.418724   1.39794 1 0 1 1 2009 0 2 1 0
    0 1 2009 0 5  3.321814   1.39794 1 1 0 1 2009 1 1 1 0
    1 2 2009 0 4  3.719754  1.612784 1 1 0 1 2009 1 2 1 0
    1 2 2009 0 4  3.497905   1.20412 1 0 0 1 2009 1 2 1 0
    0 1 2009 1 4  4.321814   1.69897 0 1 0 1 2009 1 . 0 0
    1 1 2009 1 3  3.418724  1.544068 1 0 0 1 2009 1 2 1 0
    0 1 2009 0 4  3.497905 1.5797836 1 1 0 1 2009 0 2 1 0
    0 2 2009 1 3  4.196875  1.544068 1 1 0 1 2009 0 2 1 0
    1 2 2009 1 2  3.798935 1.3424227 1 0 0 0 2009 0 2 1 0
    1 1 2009 1 5  3.798935 1.6812413 1 0 0 1 2009 0 2 1 0
    0 1 2009 1 5  3.418724   1.39794 1 0 0 1 2009 1 2 1 0
    1 1 2009 1 5  3.622844   1.30103 1 1 0 1 2009 1 2 1 0
    1 1 2009 0 4  4.020784   1.69897 0 0 0 1 2009 1 2 1 0
    1 2 2009 0 4  4.020784 1.6532125 0 1 0 1 2009 0 2 1 0
    1 2 2009 1 3  3.321814 1.2787536 1 1 0 1 2009 1 . 0 0
    1 1 2009 0 1  3.622844  1.518514 1 1 1 1 2009 0 . 0 0
    1 2 2009 1 5  3.798935   1.50515 1 0 0 1 2009 1 2 1 0
    1 1 2009 1 5  3.497905 1.6532125 1 1 0 1 2009 0 2 1 0
    1 1 2009 1 2 3.6739964 1.6532125 0 0 0 1 2009 0 2 1 0
    0 2 2009 0 1 3.5974584  1.612784 0 1 0 0 2009 0 . 0 1
    0 1 2009 0 2  3.862365  1.612784 1 1 0 1 2009 1 . 0 1
    0 2 2009 0 2  3.838563   1.39794 1 0 1 1 2009 0 2 1 1
    0 2 2009 0 3 4.1659293   1.39794 1 0 1 1 2009 0 2 1 1
    1 2 2009 0 1  4.040828   1.39794 1 1 0 1 2009 1 1 1 1
    0 2 2009 0 1 4.1682787   1.39794 0 1 0 0 2009 0 1 1 1
    0 2 2009 0 3 4.5105853  1.612784 1 1 0 1 2009 0 2 1 1
    0 1 2009 0 1  3.909776  1.612784 1 1 0 1 2009 0 2 1 1
    1 2 2009 1 1  3.884865   1.20412 1 0 0 0 2009 0 2 1 1
    1 1 2009 1 4  3.736618   1.20412 0 0 0 1 2009 1 2 1 1
    0 2 2009 0 1 4.6665144   1.69897 0 1 0 0 2009 0 . 0 1
    1 1 2009 1 1  5.101382   1.69897 1 1 0 0 2009 1 . 0 1
    1 2 2009 1 2  4.167164  1.544068 0 0 0 1 2009 1 2 1 1
    0 2 2009 1 4 3.6491024  1.544068 1 0 0 0 2009 1 2 1 1
    1 1 2009 0 4  3.665608 1.5797836 0 1 0 1 2009 0 2 1 1
    0 1 2009 1 2  4.415956 1.5797836 1 1 0 1 2009 0 2 1 1
    0 2 2009 0 2 4.5107746  1.544068 1 1 0 1 2009 1 2 1 1
    1 1 2009 0 2  5.098789  1.544068 0 1 0 0 2009 1 2 1 1
    1 1 2009 1 3   3.87634 1.3424227 0 0 0 0 2009 1 2 1 1
    1 2 2009 0 3  4.433073 1.3424227 1 0 0 1 2009 1 2 1 1
    1 2 2009 1 3 4.6136646 1.6812413 0 0 0 0 2009 1 2 1 1
    0 2 2009 1 1 4.6778274 1.6812413 1 0 0 1 2009 0 2 1 1
    0 2 2009 1 1  3.444718   1.39794 0 0 0 0 2009 1 2 1 1
    0 1 2009 1 3  3.598654   1.39794 1 0 0 1 2009 0 2 1 1
    1 2 2009 1 3 4.2007337   1.30103 1 1 0 1 2009 0 2 1 1
    1 1 2009 1 3 4.0309854   1.30103 0 1 0 1 2009 0 2 1 1
    0 1 2009 1 4 4.6363335   1.69897 0 0 0 0 2009 1 2 1 1
    1 1 2009 0 3 4.1953607   1.69897 0 0 0 0 2009 1 2 1 1
    0 2 2009 1 1 4.3825483 1.6532125 1 1 0 1 2009 0 2 1 1
    1 1 2009 1 3 4.1546836 1.6532125 0 1 0 0 2009 0 2 1 1
    1 2 2009 1 3  3.323177 1.2787536 1 1 0 0 2009 0 . 0 1
    0 2 2009 1 2  3.578914 1.2787536 0 1 0 1 2009 1 . 0 1
    0 1 2009 1 2 4.2745857  1.518514 0 1 1 1 2009 1 . 0 1
    1 1 2009 0 1 4.5480523  1.518514 1 1 1 1 2009 0 . 0 1
    1 1 2009 1 3 4.6222715   1.50515 1 0 0 1 2009 1 2 1 1
    0 2 2009 1 2  4.721875   1.50515 1 0 0 0 2009 0 2 1 1
    0 1 2009 1 4  4.245948 1.6532125 1 1 0 0 2009 1 2 1 1
    1 1 2009 0 1 4.0193195 1.6532125 1 1 0 1 2009 1 2 1 1
    1 1 2009 0 4 4.0762115 1.6532125 0 0 0 1 2009 0 2 1 1
    1 1 2009 0 3 4.5421953 1.6532125 0 0 0 1 2009 1 2 1 1
    end
    label values gender gender
    label def gender 0 "female", modify
    label def gender 1 "male", modify
    label values education education
    label def education 1 "up to 8 years basic", modify
    label def education 2 "9-15 years", modify
    label values counton counton
    label def counton 0 "no social support", modify
    label def counton 1 "yes social support", modify
    label values region region
    label def region 1 "Central", modify
    label def region 2 "East", modify
    label def region 3 "West", modify
    label def region 4 "North", modify
    label def region 5 "South", modify
    label values hindu hindu
    label def hindu 0 "not Hindu", modify
    label def hindu 1 "Hindu", modify
    label values freedom freedom
    label def freedom 0 "no freedom", modify
    label def freedom 1 "yes freedom", modify
    label values healthprob healthprob
    label def healthprob 0 "no health prob", modify
    label def healthprob 1 "yes health prob", modify
    label values corruptind corruptind
    label def corruptind 0 "no corruption", modify
    label def corruptind 1 "yes corruption", modify
    label values decade decade
    label values Prosocial Prosocial
    label def Prosocial 0 "no prosocial", modify
    label def Prosocial 1 "yes prosocial", modify
    label values INDEX_LER INDEX_LER
    label def INDEX_LER 1 "Suffering", modify
    label def INDEX_LER 2 "Struggling", modify
    
    
    //earlier
    gologit2 INDEX_LER i.Prosocial i.freedom i.counton i.healthprob ///
    i.education i.corruptind c.logincome if year==2009, ///
    vce(robust) autofit gamma force
    mat l e(b)
    estimates store ppo2009
    
    *MARGINSPLOT
    set scheme s1color
    margins, dydx( Prosocial freedom counton healthprob corruptind logincome)
    marginsplot, noci allsimplelabels nolabel saving(gr1, replace)
    
    *USING COEFPLOT
    estimates restore ppo2009
    margins, dydx( Prosocial freedom counton healthprob corruptind logincome) predict(outcome(1)) post
    est sto m1
    
    estimates restore ppo2009
    margins, dydx( Prosocial freedom counton healthprob corruptind logincome) predict(outcome(2)) post
    est sto m2
    
    coefplot (m1, msymbol(C) lcolor(purple) mcolor(purple*.7)) ///
    (m2, msymbol(T)), lcolor(green) mcolor(green) msize(large) ///
    recast(connected) drop(_cons) noci vert nooffset xlab(1(1)6) ///
    ytitle("Effects on Probability") xtitle("Effects with respect to") ///
    title("Average Marginal Effects", size(medlarge)) saving(gr2, replace)
    
    gr combine gr1.gph gr2.gph
    Res.:

    Click image for larger version

Name:	Graph.png
Views:	1
Size:	68.2 KB
ID:	1613568

    Comment


    • #3
      Andrew, You are a master at graphics in Stata. Thanks so much. Using the user-written coefplot from SSC and your code, I was able to make this graph, which is exactly what I wanted:



      Here is the complete code I used to make the above graph, in case this helps anyone:

      Code:
      *regression first
      gologit2 INDEX_LER i.Prosocial i.freedom i.counton i.healthprob ///
      i.education i.corruptind c.logincome c.logage i.gender i.region i.hindu ///
      i.decade if year==2009, ///
      vce(robust) autofit gamma
      mat l e(b)
      estimates store ppo2009
      
      *THEN MARGINS TO USE COEFPLOT
      estimates restore ppo2009
      margins, dydx( Prosocial freedom counton healthprob corruptind logincome) predict(outcome(1)) post
      est sto m1
      
      estimates restore ppo2009
      margins, dydx( Prosocial freedom counton healthprob corruptind logincome) predict(outcome(2)) post
      est sto m2
      
      estimates restore ppo2009
      margins, dydx( Prosocial freedom counton healthprob corruptind logincome) predict(outcome(3)) post
      est sto m3
      
      *now to graph those
      coefplot ///
      (m1, label(suffering) mcolor(purple) lcolor(purple) mlabcolor(purple) msymbol(O)) ///
      (m2, label(struggling) mcolor(blue) lcolor(blue) mlabcolor(blue) msymbol(D)) ///
      (m3, label(thriving) mcolor(green) lcolor(green) mlabcolor(green) msymbol(T)) ///
      , recast(connected) drop(_cons) noci nooffset vertical ///
      xlabel(1 "prosocial" 2 "freedom" 3 "support" 4 "bad health" 5 "corruption" ///
      6 "log{subscript:10} income", labsize(small)) ///
      ytitle("Pr(SWB Outcome Category)", size(*.8)) ///
      xtitle("Predictors", margin(medium)) ///
      grid(between glpattern(dash) glwidth(*0.5) glcolor(gray)) ///
      yline(0, lwidth(medium) lcolor(black) lpattern(solid)) ///
      ylabel(, angle(0)) ///
      msize(medium) ///
      mlabel(cond(@pval<.001, "***", ///
      cond(@pval<.01, "**", ///
      cond(@pval<.05, "*", ///
      cond(@pval>.05, "", ///
      string(@pval,"%9.3f")))))) ///
      mlabposition(2) mlabgap(-.5) mlabsize(large) /// got sig-marker label idea from Andrew Musau on statalist.org; love it
      legend(order(1 "{bf:Suffering}" 2 "{bf:Struggling}" 3 "{bf:Thriving}") ///
      rows(1) title("SWB Outcome Categories", size(*.8)) position(12) ring(2) ///
      region(fcolor(dimgray) lcolor(navy) lwidth(thick) margin(medium)) ) ///
      title("Average Marginal Effects of SWB Predictors in 2009 PPO Model", ///
      span size(*.9) margin(medium)) ///
      note("* p < .05; ** p < .01; *** p < .001" ///
      "Note. Source is Gallup World Poll India data (n = 8,047)", linegap(1.5) span) ///
      name(marginscoef, replace)
      graph export marginscoef.svg, replace

      A few things, in case this is helpful to anyone, and to help me be a good forum mate moving forward:
      1. I could not find any way to exclude base categories in marginsplot. That seemed like a potentially good suggestion to track down but I see no options. Edit: Actually, I think marginsplot does, in a way, exclude base categories, right? with my binary indicators for example, it's plotting the margins for 1 (not 0, the base category) for each.
      2. I tried simply swapping the order of variables in the regression model and the margins and marginsplots commands, putting the one continuous predictor (logincome) first instead of at the end, and this actually fixed my starting problem as well. I'm not sure why it fixed it though, and I would love to understand, if anyone happens to know. Please see below for code and graphic display of what I mean.
      3. I think coefplot (SSC) is awesome and a superior fix anyway.
      4. I've never used dataex before. I realize what I provided in #1 was not enough data to use. How can I tell/what should I provide differently next time?
      Here's the other fix, instead of using coefplot (SSC) that also worked to stay with marginsplot:


      Code:
      //orig order
      gologit2 INDEX_LER i.Prosocial i.freedom i.counton i.healthprob ///
      i.education i.corruptind c.logincome c.logage i.gender i.region i.hindu ///
      i.decade if year==2009, ///
      vce(robust) autofit gamma
      estimates store ppo2009
      margins, dydx(Prosocial freedom counton healthprob corruptind logincome)
      marginsplot, noci allsimplelabels title(orig order) ///
      xlabel(11 `""logincome" "over here" "not good"', labsize(vsmall)) ///
      saving(origorder, replace)
      
      //new order
      gologit2 INDEX_LER c.logincome i.Prosocial i.freedom i.counton i.healthprob ///
      i.education i.corruptind c.logage i.gender i.region i.hindu ///
      i.decade if year==2009, ///
      vce(robust) autofit gamma
      estimates store ppo2009
      margins, dydx( logincome Prosocial freedom counton healthprob corruptind)
      marginsplot, noci allsimplelabels title(new order) ///
      xlabel(1 `""logincome" "over here" "no prob"', labsize(vsmall)) ///
      saving(neworder, replace)
      
      //makes no sense to me but I love coefplot anyway so it's all good
      gr combine origorder.gph neworder.gph




      Cheers,
      Erika
      Last edited by Erika Sanborne; 07 Jun 2021, 12:16. Reason: clarifying point #1
      I am using Stata SE 16.1.

      Comment


      • #4
        1. I could not find any way to exclude base categories in marginsplot. That seemed like a potentially good suggestion to track down but I see no options. Edit: Actually, I think marginsplot does, in a way, exclude base categories, right? with my binary indicators for example, it's plotting the margins for 1 (not 0, the base category) for each.
        The way to look at it is that the base categories are empty, so nothing is plotted. But they take positions 1,3, 5, 7 and 9 in your graph's x-axis in #1. Your workaround of reversing the order of coefficients works because you have only 1 continuous variable, and it takes position 1 instead of 11 on the x-axis, whereas the base categories are placed at 2,4, 6, 8 and 10 with the non-base categories at 3, 5, 7, 9 and 11.

        1. I've never used dataex before. I realize what I provided in #1 was not enough data to use. How can I tell/what should I provide differently next time?
        You just run your code on the dataex sample and see if it runs.
        Last edited by Andrew Musau; 07 Jun 2021, 13:41.

        Comment

        Working...
        X