Announcement

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

  • Overlaying two marginsplot

    Dear Statalisters,

    Here are the codes for 'margins' after two regressions :



    Code:
    reg cpauc2 i.rand c.dvpa0 i.rand#c.dvpa0 //model-1
    margins i.rand,at(dvpa0=(10(10)100))
    marginsplot
    
    reg cpauc2 i.rand c.dvpa2 i.rand#c.dvpa2 //model-2
    margins i.rand,at(dvpa2=(10(10)100))
    marginsplot

    I would like to know if it is possible to overlay these two 'margins' plots together and make one plot. User written programme 'combomarginsplot' will not work as the 'at' 'variables' for two models are different (tried and got error message). Don't want 'graph combine' either as it will combine two plots side by side or up/down, whereas what I am looking forward to is to overlaying the two graphs on each other. Is there any other way to achieve that?

    Your comments and suggestions are always very helpful and many thanks in advance.

    All the best,
    Roman

  • #2
    Roman,

    You may fund a way to do this on the excellent UCLA Web pages about Stata. One solution is given in their article How can I graph the results of the margins command? (Stata 11) at
    http://www.ats.ucla.edu/stat/stata/f...gins_graph.htm

    Sincerely,
    Alan Neustadtl

    Comment


    • #3
      coefplot (written by Ben Jann; available from SSC) allows overlaying the results of multiple margin results.

      coefplot is explained in detail here: ftp://repec.sowi.unibe.ch/files/wp1/...3-coefplot.pdf
      and here: http://www.stata-journal.com/article...article=gr0059

      Here is an example using the auto dataset:

      Code:
      sysuse auto, clear
      
      egen mpg_z = std(mpg)
      egen headroom_z = std(headroom)
      replace headroom_z = headroom_z * -1
      
      reg price i.foreign##c.mpg_z c.headroom_z
      margins , dydx(foreign) at(mpg_z=(-2(0.1)2)) post
      est store model1
      
      reg price i.foreign##c.headroom_z c.mpg_z
      margins , dydx(foreign) at(headroom_z=(-2(0.1)2)) post
      est store model2
      
      coefplot model1 model2, at xtitle("mpg_z & headroom_z")

      Comment


      • #4
        Dear Alan and Michael,

        Thanks to both of you. UCLA site seems to be a daunting solution but worth if Michael's suggested coefplot does not work. The coefplot in my case overlaying two plots but I am not getting the linear fit to the point estimates in the plot. The line is arbitrarily moving up/downwards. See the graph attached. Using the sort option did not work either. I will wait for further solution to this. If nothing comes up, will undertake that daunting task. Again many many thanks to both of you.


        Code:
        // Model-1-:
        reg cpaucln2 cpaucln0c i.rand c.dvpa0 i.rand#c.dvpa0
        
        
        margins i.rand,at(dvpa0=(10(10)80)) post
        est store Baseline
        
        
        reg cpaucln2 cpaucln0c i.rand dvpa0 c.dvpa2 i.rand#c.dvpa2
        
        margins i.rand,at(dvpa2=(10(10)80)) post
        est store Followup
        
        coefplot m1 m2, at xtitle("Baseline & Followup ") noci sort recast(line) lwidth(*1)
        Roman

        Comment


        • #5
          Have you looked at the graph without using the "recast(line)" option? When I specify "recast(line)" in my example from above, the plot also looks odd.

          In my suggestion, I plotted the effect of foreign. If you want to plot predicted values for each level and each with a different color, you could consider this:

          Code:
          sysuse auto, clear
          
          egen mpg_z = std(mpg)
          egen headroom_z = std(headroom)
          replace headroom_z = headroom_z * -1
          
          reg price i.foreign##c.mpg_z c.headroom_z
          margins ,  at(mpg_z=(-2(0.1)2) foreign == 0) post
          est store model1_0
          
          reg price i.foreign##c.mpg_z c.headroom_z
          margins ,  at(mpg_z=(-2(0.1)2) foreign == 1) post
          est store model1_1
          
          reg price i.foreign##c.headroom_z c.mpg_z
          margins , at(headroom_z=(-2(0.1)2) foreign == 0) post
          est store model2_0
          
          reg price i.foreign##c.headroom_z c.mpg_z
          margins , at(headroom_z=(-2(0.1)2) foreign == 1) post
          est store model2_1
          
          coefplot model1_0 model1_1 model2_0 model2_1, at xtitle("mpg_z & headroom_z") noci recast(line)

          Comment


          • #6
            Roman,

            The UCLA solution does have some interesting programming. But, the complexity can be reduced substantially if you really just need the estimates. Here is some Stata code that you might find helpful:
            Code:
            sysuse auto, clear
            
            /* Estimate Model 1 and store margins as variables */
            regress mpg weight
            margins, at(weight=(1800(200)4800)) post
            matrix est=e(at), e(b)'
            svmat est, names(modelA)
            
            /* Estimate Model 2 and store margins as variables */
            regress mpg c.weight##c.weight
            margins, at(weight=(1800(200)4800)) post
            matrix est=e(at), e(b)'
            svmat est, names(modelB)
            
            /* List the stored values */
            list mod* if !missing(modelA1)
            
            /* Create the visualization of the two models */
            tw (line modelA2 modelB2 modelA1)
            The -post- option to the -margins- command makes the results available in a number of matrices. For example, the matrix e(at) contains the "at" values used. In this example:

            Code:
            . matrix list e(at)
            
            e(at)[16,1]
                    weight
             1._at    1800
             2._at    2000
             3._at    2200
             4._at    2400
             5._at    2600
             6._at    2800
             7._at    3000
             8._at    3200
             9._at    3400
            10._at    3600
            11._at    3800
            12._at    4000
            13._at    4200
            14._at    4400
            15._at    4600
            16._at    4800
            And the matrix e(b) contains the following:
            Code:
            . matrix list e(b)
            
            e(b)[1,16]
                        1.         2.         3.         4.         5.         6.         7.         8.         9.        10.
                      _at        _at        _at        _at        _at        _at        _at        _at        _at        _at
            y1  29.989629  28.164561  26.445445  24.832282  23.325071  21.923811  20.628504  19.439149  18.355746  17.378295
            
                       11.        12.        13.        14.        15.        16.
                      _at        _at        _at        _at        _at        _at
            y1  16.506796  15.741249  15.081654  14.528012  14.080321  13.738583
            To put these into the same matrix the e(b) matrix has to be transposed and then concatenated as a new column to a matrix. The following line does that work creating a new matrix called ests:

            Code:
            matrix est=e(at), e(b)'
            Then, I save the contents of the matrix as new variables:

            Code:
            svmat est, names(modelA)
            Finally, the new variables are visualized.

            Hopefully this helps.

            Sincerely,
            Alan

            Comment


            • #7
              Dear Alan, many thanks for your help and time. It is worth going for this I am sure as I could practice a little bit of matrix manipulation but Michael's suggestion worked nicely and perhaps that is what I needed at this rush time.

              Michael, I think separate estimation for each level is the key here. I basically needed one level (group) from each model so reduced the estimation to one group. Without recast you only get the coefficient not the lines connected. However to let you know, recast' didn't cause any problem with this separate estimation but you do not get the markers for each point (only two lines from two models). Therefore, I used connect(l) option instead of 'recast' to get both lines and markers. see below the code and the graph.

              Many many thanks again for both of your's valuable contributions.

              Code:
              margins i(1).rand,at(mvpa0=(10(10)80)) post
              est store Baseline
              
              margins i(1).rand,at(mvpa2=(10(10)80)) post
              
              est store Followup
              
              coefplot Baseline Followup, at xtitle(" ") noci lwidth(*1) connect(l)
              Roman

              Comment


              • #8
                Hi Michael/Alan/anyone,

                One last question on the above graph. Is it possible to specify different line pattern for two lines i.e. one solid and one dashed or one red colored and the other green? My current specification renders to both lines. See my current code below:


                Code:
                coefplot Baseline Followup, at  connect(l) noci  ///
                xtitle(" " "DVPA",col(black)) lcol(black) lwidth(*1) msym(S) mcol(black) ///
                ylab( ,nogrid ang(hor)labsize(vsmall)labcol(black)) ///
                xlab(10 (10) 80,labsize(small)labcol(black)) ///
                legend(region(col(white))size(small)) ///
                ytitle("AUC",col(black)size(small)) ///
                title("Adjusted effect of DVPA AUC",size(medium)col(black)) ///
                graphregion(col(white))
                All the best

                Roman

                Comment


                • #9
                  Hi Roman,

                  you can change the look of each line by specifying the options directly after the stored margins results using parentheses. Here is an example:

                  Code:
                  sysuse auto, clear
                  
                  egen mpg_z = std(mpg)
                  egen headroom_z = std(headroom)
                  replace headroom_z = headroom_z * -1
                  
                  reg price i.foreign##c.mpg_z c.headroom_z
                  margins ,  at(mpg_z=(-2(0.1)2) foreign == 0) post
                  est store model1_0
                  
                  reg price i.foreign##c.mpg_z c.headroom_z
                  margins ,  at(mpg_z=(-2(0.1)2) foreign == 1) post
                  est store model1_1
                  
                  reg price i.foreign##c.headroom_z c.mpg_z
                  margins , at(headroom_z=(-2(0.1)2) foreign == 0) post
                  est store model2_0
                  
                  reg price i.foreign##c.headroom_z c.mpg_z
                  margins , at(headroom_z=(-2(0.1)2) foreign == 1) post
                  est store model2_1
                  
                  coefplot ///
                  (model1_0, recast(line) lpattern(dot) lcolor(orange)) ///
                  (model1_1, recast(line) lpattern(dash) lcolor(blue)) ///
                  (model2_0, msym(Oh) mcolor(pink) msize(large)) ///
                  (model2_1, recast(line)), at xtitle("mpg_z & headroom_z") noci

                  Comment


                  • #10
                    This is so helpful. Many thanks Michael.
                    Regards
                    Roman

                    Comment


                    • #11
                      Roman, for what you want to do (depicted in post #7), a somewhat simpler solution might have been to use two variables. One stores mvpa number (0 or 2 in your example) and the other stores the values 10-80. Then, you'd run code such as:

                      Code:
                      margins, at(mvpa = (10(10)80) mvpa_num = (0 2))
                      marginsplot
                      This thread has been helpful, however, because I'm trying to plot two predicted lines with different values (e.g., different mvpa values in Roman's example). Thanks!

                      Comment

                      Working...
                      X