Announcement

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

  • Graph Titles with Foreach

    Hi,
    I'm trying to create 3 side by side graph with the estimations from mlogit.

    So this is my model and predictions:
    eststo mlogit3: mlogit part c.congr##c.normal $controls, robust

    sum normal if e(sample), detail
    return list
    mgen,at((means) $controls congr=(0(1)7) normal=(`r(p10)' `r(p50)' `r(p90)') (median) gender fed) saving(mlogitpartyinst, replace)

    Now I created macros to generate the graphs:
    local i=1
    foreach m in .5102040767669678 .8367347121238708 .9854227304458618{
    twoway (rarea _ll0 _ul0 _congr if _normal==`m', color(pink%50)) (rarea _ll1 _ul1 _congr if _normal==`m', color(green%50)) (rarea _ll2 _ul2 _congr if _normal==`m', color(navy%50)) (rarea _ll3 _ul3 _congr if _normal==`m', color(orange%50)) (line _pr0 _congr if _normal==`m', lcol(pink%50) lpat(solid)) (line _pr1 _congr if _normalt==`m', lcol(green%50) lpat(solid)) (line _pr2 _congr if _normal==`m', lcol(navy%50) lpat(solid)) (line _pr3 _congr if _normal==`m', lcol(orange%50) lpat(solid)) (hist congr if e(sample) & normal==`m', percent yaxis(2) yscale(off axis(2)) color(black%15) lcolor(white) xlab(0(1)8)), xlab(0(1)7) ylab (0(.1).8) xtitle("Distance") name(margins`i', replace) title("Party Institutionalization(`i')")
    loc ++i
    }

    I produce the graph that I want with this code. However, I also want to include different titles for 3 graphs like this: normal (10%) normal (50%) normal (90%). I tried to do that with another local but it iterates the code 3 times for each title. How can I include the title?


  • #2
    Hi Melisa,

    Please note that careful attention to the posting guidelines in the FAQ above would probably have gotten you a solution faster, and without careful attention to the posting guidelines you risk not receiving a response at all. I for one read this yesterday and decided that I didn't want to try to parse through the formatting on your code. In this case, code tags and careful formatting would have been very helpful.

    That being said, I think your original strategy to use another local macro is basically correct. However, It sounds like when you say you used another local macro, you also used another foreach loop. A foreach loop is distinct from a macro. I think it might be better to use your original foreach loop to determine the correct title on each iteration. The best way to do this from a programing perspective is to have a list of your three titles and to use `i' to select the correct element from the list on each iteration. I'm afraid, however, my Stata-fu is not yet strong enough to do this - at least not in a way that is easy to understand, so here is a somewhat ugly but workable solution:

    Code:
    local i=1
    foreach m in .5102040767669678 .8367347121238708 .9854227304458618{
        if `i'==1{
            local title = "normal (10%)"
        }
        else if `i'==2{
            local title = "normal (50%)"
        }
        else if `i'==3{
            local title = "normal (90%)"
        }
        else{
            exit(error("unknown title specified."))
        }
        display "`title'"
        loc ++i
    }
    So, putting it all together, I believe something like this should work:

    Code:
    local i=1
    foreach m in .5102040767669678 .8367347121238708 .9854227304458618{
        if `i'==1{
            local title = "normal (10%)"
        }
        else if `i'==2{
            local title = "normal (50%)"
        }
        else if `i'==3{
            local title = "normal (90%)"
        }
        else{
           display "unknown title specified!"
        }
        twoway (rarea _ll0 _ul0 _congr if _normal==`m', color(pink%50)) ///
          (rarea _ll1 _ul1 _congr if _normal==`m', color(green%50)) ///
          (rarea _ll2 _ul2 _congr if _normal==`m', color(navy%50)) ///
          (rarea _ll3 _ul3 _congr if _normal==`m', color(orange%50)) ///
          (line _pr0 _congr if _normal==`m', lcol(pink%50) lpat(solid))///
          (line _pr1 _congr if _normalt==`m', lcol(green%50) lpat(solid)) ///
          (line _pr2 _congr if _normal==`m', lcol(navy%50) lpat(solid)) ///
          (line _pr3 _congr if _normal==`m', lcol(orange%50) lpat(solid)) ///
          (hist congr if e(sample) & normal==`m', ///
          percent yaxis(2) yscale(off axis(2)) color(black%15) ///
          lcolor(white) xlab(0(1)8)), xlab(0(1)7) ylab (0(.1).8) ///
          xtitle("Distance") name(margins`i', replace) title("`title'")
        loc ++i
    }
    Does anyone else know a better way to do this? I would welcome a more elegant solution.
    Last edited by Daniel Schaefer; 28 Jun 2022, 11:15.

    Comment


    • #3
      if `i'==1{
      local title = "normal (10%)"
      }
      else if `i'==2{
      local title = "normal (50%)"
      }
      else if `i'==3{
      local title = "normal (90%)"
      can be reduced to

      Code:
      local title = cond(`i'==1, "normal (10%)", cond(`i'==2, "normal (50%)", "normal (90%)"))

      Comment


      • #4
        Within a loop over local macro i = 1, 2, 3

        Code:
        local title = "normal" + word("(10%) (50%) (90%)", `i')

        Comment


        • #5
          Thank you very much for the answers, all worked! Sorry for not following the posting guidelines, won't happen again.

          Comment


          • #6
            Thanks from me as well. After reading this thread, I found the "functions by category" section of the documentation, which describes functions like cond() and word(). I am going to make an effort to learn this library!

            Comment

            Working...
            X