Announcement

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

  • Marginsplot: using the original values instead of log values in the x-scale

    Dear all,

    I have run a panel probit model and I want to plot marginal effects for different values of wealth (which has been transformed to logs) at the mean values of other controls. I would want the x-scale to be transformed again to the original values, but this seems pretty difficult to be achieved.

    My initial thought was as follows, applying brute force, but this is not working:
    1. I want the x-axis to have values (in thousand dollars) of the style 0(20)100 200(100)500 750 1000, say, for 0 to 1M€ wealth.
    2. Then, I just need to know the exact values in logs for my target values, and use margins, at command.
    3. Then, I can just edit the labels and write the values in the original scale.

    This is my code:
    Code:
    xtprobit dep_var log_wealth controls, pa vce(robust)
    margins, dydx(log_wealth controls)
    margins, at (log_wealth= (0 9.9 10.6 11 11.29 11.51 11.92 12.206 12.612 12.9 13.12 13.53 13.516) mean(controls))
    *the vales for log_wealth are the log transformed values of my target values*
    marginsplot, noci
    I also attach my outcome.

    Of course, I would want the ticks to be evenly spaced (as if I were using the original scale), but those values are not evenly spaced in log scale, and thus, the graph looks terrible.
    I also thought in using mylabels command and edit the xscale directly in marginsplot, but this does not seem the correct approach. I believe that the problem should be fixed when I define which values I am evaluating at, this is in the margins, at command rather than in marginsplot.

    Does anybody know a potential way to get the original instead of the log scale in the x-axis?

    Many thanks in advance,
    Attached Files
    Last edited by Borja Urrea; 14 Jul 2021, 08:33.

  • #2
    -marginsplot- does not have that kind of flexibility. You need to re-run your -margins- command adding the undocumented -saving()- option to save the -margins- results in a new .dta file. Then you can -use- that file, calculate a new variable that exponentiates the log transformed values to recover the originals, and work with the -graph- command to get the desired results. The naming of the variables in the saved file will be a little weird, but if you look them over carefully it will become clear which variable represents which.

    Comment


    • #3
      Patrick Royston's mcp command (available from SSC) may be able to do what you want, or you may be able to adapt the little tricks it does. Example:

      Code:
      use https://www.stata-press.com/data/r17/union, clear
      gen lnage = ln(age)
      xtprobit union lnage grade i.not_smsa south##c.year, pa vce(robust)
      summarize age
      range w1 r(min) r(max) 20
      generate lnw1 = ln(w1)
      mcp age (lnage), var1(w1 (lnw1))
      Royston's paper descriping the command is at

      https://www.stata-journal.com/articl...article=gr0056

      My summary of the command is at

      https://www3.nd.edu/~rwilliam/xsoc73994/Margins03.pdf

      See especially pp. 7-10, "Models with transformed X."

      Just make sure the results are right! i.e. the graphs with wealth and log wealth really are showing equivalent results.

      Even if mcp doesn't meet your needs in this case, I think it is a great command to have. I use it a lot.

      Let us know if this meets your needs, and if so post the graph mcp gives you.

      Note: one problem you might have is the X axis will be very wide, causing lower values of wealth to get squished together. mcp has some ways for dealing with that too.

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

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

      Comment


      • #4
        In addition to Richard's and Clyde's suggestions, I would also suggest using the userwritten command -f_able-

        Your regression will require a few changes, Below an example

        Code:
        webuse union, clear
        ** create the Log variable with -fgen-
        fgen logage=log(age)
        ** notice im also adding o.age, so it ignores age, but is still in the list of explanatory variables.
         xtprobit union logage o.age grade i.not_smsa south##c.year
        ** and indicate its a constructed variable with f_able
         f_able logage, auto
        ** you may need to add the option noestimcheck
        ** notice Im ploting against age, not logage
         margins, at (age= (16(2)46) ) atmean noestimcheck
         marginsplot, name(m1, replace)
         
        ** you can compare the example to a case where age is used directly
         xtprobit union age grade i.not_smsa south##c.year
         margins, at (age= (16(2)46) ) atmean noestimcheck
         marginsplot, name(m2, replace)
         graph combine m1 m2, ycommon
        Click image for larger version

Name:	Graph.png
Views:	1
Size:	35.2 KB
ID:	1618840

        Comment


        • #5
          Response to #2:
          Dear Clyde,

          Thanks a lot for your suggestion. I did not know I could use saving option with margins. I have tried your suggestion and it seems to work, but I have a problem with the graph. Instead of displaying the entire range for wealth, since I have some observations that are just too big, I would want to modify the range of the x-axis, so I have obs between say 0 and 1M-1.5M. I am trying to do this using the- xscale(range())- axis suboption, but it does not seem to work. Deleting those extreme observations (very high log_wealth) is not an option either, since the graph is still displaying the original range of values. Manually editing the graph is not working, either. Do you have any suggestions?

          Code:
           *Recover the original values:  rename _at16 log_wealth
             gen wealth = exp(log_wealth)/1000 //So I have wealth in thousand dollars
             bro wealth
             *Graph:
             twoway line _margin wealth, xscale(range(0(20)1500))
          This is how the graph looks like:

          Click image for larger version

Name:	statalist2.jpg
Views:	1
Size:	18.2 KB
ID:	1618851


          Response to #3:

          Dear Richard,

          Thanks a lot for your response (and also for your useful margins articles which have been of great help for my dissertation!). And, of course, thanks for help me discovering mcp command which looks very useful.
          I have tried your advice, by typing the following codes, but Stata gives me an error when I try to plot marginal effects for log_wealth using mcp: "invalid numlist has too many elements" r(123).
          Do you know what might be going wrong?

          Code:
          *Attempt 1:
          mcp log_wealth
          *Attempt 2:
          mcp log_wealth, margopts(atmeans)
          *Attempt 3: 0-18 is the range of log_wealth
          mcp log_wealth at1(log_wealth = (0(1)18))

          Comment


          • #6
            mcp can plot around 70 values of x, and will give errors if x has more unique values than that. To get around that add an option like var1(20), which will divide the range up into 20 points which is usually more than enough. My handout goes over that.

            You can probably fix your current graphing commands but with mcp you can easily limit the range graphed. See the section that starts on p. 4 of my handout.

            Whatever mcp does can no doubt be done n other ways, but I like mcp because I don’t have to figure out what those other ways are.
            -------------------------------------------
            Richard Williams, Notre Dame Dept of Sociology
            StataNow Version: 19.5 MP (2 processor)

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

            Comment


            • #7
              In response to #4:

              Hola Fernando,

              Sorry that I did not refresh the page and did not see your comment before publishing my last response. Thanks a ton for your suggestion.
              I quickly tried your suggestion and it seems to work perfectly. I am attaching the graph I got. It looks great.

              Click image for larger version

Name:	riosavila.jpg
Views:	1
Size:	21.4 KB
ID:	1618859

              Comment


              • #8
                That is a nice looking graph! If you care to try it, I’d be curious to see if mcp produces basically the same graph or not.

                i wish Fernando’s command was basically built into Stata’s factor variable notation, but for whatever reason it hasn’t been.
                -------------------------------------------
                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
                  In response to #6:

                  Dear Richard,

                  I have tried your suggestion and it works, once I include the var1(20) it displays the correct graph for log_wealth. I have tried the rest of your code and the output is similar to what I got with Clyde's suggestions, but I bet that by playing a bit with the -range- command I can get the desired graph.

                  Thanks again for your input.

                  Comment


                  • #10
                    In response to #8:

                    I have tried to get a similar graph by writing the following code:

                    Code:
                    xtprobit depvar log_wealth controls, pa vce(robust)
                    sum gross_wealth
                    range w2 0 1500000 20
                    mcp gross_wealth (log_wealth), var1(w2 (lnw2))
                    However, it displays an error message, r(122), telling that there has been a problem executing margins.

                    Comment


                    • #11
                      You haven't followed all the steps shown in post #3, e.g. you haven't computed lnw2.

                      Taking log of 0 may also create problems. Maybe just start the range at $1.
                      -------------------------------------------
                      Richard Williams, Notre Dame Dept of Sociology
                      StataNow Version: 19.5 MP (2 processor)

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

                      Comment


                      • #12
                        Dear Richard,

                        Sorry because I forgot to write that line, but I followed all the steps. I should have added gen lnw2=log(w2). I did not copy/paste the code from the .do file but write it (I run Stata in another computer9 and that's the source of the error. Indeed, as you pointed out, the error came from the fact that I had 0 for the lower bound of the range. However, the graph I got looks very different from using Fernando's suggestion, above all for very small values of gross_wealth (which are not very common in my sample: of 8000 obs more than 7600 have assets which are worth at least 20K).

                        I also amended my last line of code to be:
                        Code:
                         
                         mcp gross_wealth (log_wealth), var1(w2 (lnw2)) margopts(atmeans)
                        But eventually, I got the same result, see attached.
                        Click image for larger version

Name:	richard.jpg
Views:	1
Size:	18.4 KB
ID:	1618996

                        Comment


                        • #13
                          Fernando's graph looks nicer! But that may be partly because the highest value in his was 1 million, whereas the mcp graph goes to 1.5 million. Maybe change your range command to

                          range w1 1 1000000 20

                          Or, maybe

                          range w1 1 1000000 50
                          -------------------------------------------
                          Richard Williams, Notre Dame Dept of Sociology
                          StataNow Version: 19.5 MP (2 processor)

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

                          Comment


                          • #14
                            Hello, I am trying to do this but with the y-axis using original values instead of logged but I can't seem to get it to work.

                            This is my current code:
                            Code:
                            marginsplot, recast(line) noci plotopts(lcolor("`CAG_`e''")) title("CAG `e'") ytitle("logNfL pg/mL")  ///
                                            addplot( ///
                                                        (scatter logNfL Age if disease_grp==1 & CAG==`e',  mcolor("`CAG_`e''") ///
                                                    ) ///
                                            name(`model'_`e', replace)
                            I tried Fernando's way but it didn't seem to work for the y-axis.

                            Comment

                            Working...
                            X