Announcement

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

  • Looping

    Hello,

    I got a question with regards to the use of loops.
    I have panel data and would like to plot the savings rate for each country (using a seperate graph for each country and then combining them in one graph).
    Currently, I have the following code.

    PHP Code:
    line savings_rate year if cid=="AT"xtitle(""ytitle(""title("Austria")
    graph save Graph "C:\Users\wvanlaer\Dropbox\Doctoraat\Artikel sparen\Stata\AT.gph"

    line savings_rate year if cid=="BE"xtitle(""ytitle(""title("Belgium")
    graph save Graph "C:\Users\wvanlaer\Dropbox\Doctoraat\Artikel sparen\Stata\BE.gph"

    line savings_rate year if cid=="BG"xtitle(""ytitle(""title("Bulgaria")
    graph save Graph "C:\Users\wvanlaer\Dropbox\Doctoraat\Artikel sparen\Stata\BG.gph"

    line savings_rate year if cid=="CY"xtitle(""ytitle(""title("Cyprus")
    graph save Graph "C:\Users\wvanlaer\Dropbox\Doctoraat\Artikel sparen\Stata\CY.gph"

    line savings_rate year if cid=="CZ"xtitle(""ytitle(""title("Czech Republic")
    graph save Graph "C:\Users\wvanlaer\Dropbox\Doctoraat\Artikel sparen\Stata\CZ.gph"

    line savings_rate year if cid=="DE"xtitle(""ytitle(""title("Germany")
    graph save Graph "C:\Users\wvanlaer\Dropbox\Doctoraat\Artikel sparen\Stata\DE.gph"

    line savings_rate year if cid=="DK"xtitle(""ytitle(""title("Denmark")
    graph save Graph "C:\Users\wvanlaer\Dropbox\Doctoraat\Artikel sparen\Stata\DK.gph"

    line savings_rate year if cid=="ES"xtitle(""ytitle(""title("Spain")
    graph save Graph "C:\Users\wvanlaer\Dropbox\Doctoraat\Artikel sparen\Stata\ES.gph"

    line savings_rate year if cid=="FI"xtitle(""ytitle(""title("Finland")
    graph save Graph "C:\Users\wvanlaer\Dropbox\Doctoraat\Artikel sparen\Stata\FI.gph"

    line savings_rate year if cid=="FR"xtitle(""ytitle(""title("France")
    graph save Graph "C:\Users\wvanlaer\Dropbox\Doctoraat\Artikel sparen\Stata\FR.gph"

    line savings_rate year if cid=="HU"xtitle(""ytitle(""title("Hungary")
    graph save Graph "C:\Users\wvanlaer\Dropbox\Doctoraat\Artikel sparen\Stata\HU.gph"

    line savings_rate year if cid=="IE"xtitle(""ytitle(""title("Ireland")
    graph save Graph "C:\Users\wvanlaer\Dropbox\Doctoraat\Artikel sparen\Stata\IE.gph"

    line savings_rate year if cid=="IT"xtitle(""ytitle(""title("Italy")
    graph save Graph "C:\Users\wvanlaer\Dropbox\Doctoraat\Artikel sparen\Stata\IT.gph"

    line savings_rate year if cid=="NL"xtitle(""ytitle(""title("Netherlands")
    graph save Graph "C:\Users\wvanlaer\Dropbox\Doctoraat\Artikel sparen\Stata\NL.gph"

    line savings_rate year if cid=="PT"xtitle(""ytitle(""title("Portugal")
    graph save Graph "C:\Users\wvanlaer\Dropbox\Doctoraat\Artikel sparen\Stata\PT.gph"

    line savings_rate year if cid=="SE"xtitle(""ytitle(""title("Sweden")
    graph save Graph "C:\Users\wvanlaer\Dropbox\Doctoraat\Artikel sparen\Stata\SE.gph"

    line savings_rate year if cid=="SI"xtitle(""ytitle(""title("Slovenia")
    graph save Graph "C:\Users\wvanlaer\Dropbox\Doctoraat\Artikel sparen\Stata\SI.gph"

    line savings_rate year if cid=="SK"xtitle(""ytitle(""title("Slovakia")
    graph save Graph "C:\Users\wvanlaer\Dropbox\Doctoraat\Artikel sparen\Stata\SK.gph"

    line savings_rate year if cid=="UK"xtitle(""ytitle(""title("United Kingdom")
    graph save Graph "C:\Users\wvanlaer\Dropbox\Doctoraat\Artikel sparen\Stata\UK.gph"


    gr combine "C:\Users\wvanlaer\Dropbox\Doctoraat\Artikel sparen\Stata\AT.gph" "C:\Users\wvanlaer\Dropbox\Doctoraat\Artikel sparen\Stata\BE.gph" "C:\Users\wvanlaer\Dropbox\Doctoraat\Artikel sparen\Stata\BG.gph" "C:\Users\wvanlaer\Dropbox\Doctoraat\Artikel sparen\Stata\CY.gph" "C:\Users\wvanlaer\Dropbox\Doctoraat\Artikel sparen\Stata\CZ.gph" "C:\Users\wvanlaer\Dropbox\Doctoraat\Artikel sparen\Stata\DE.gph" "C:\Users\wvanlaer\Dropbox\Doctoraat\Artikel sparen\Stata\DK.gph" "C:\Users\wvanlaer\Dropbox\Doctoraat\Artikel sparen\Stata\ES.gph" "C:\Users\wvanlaer\Dropbox\Doctoraat\Artikel sparen\Stata\FI.gph" "C:\Users\wvanlaer\Dropbox\Doctoraat\Artikel sparen\Stata\FR.gph" "C:\Users\wvanlaer\Dropbox\Doctoraat\Artikel sparen\Stata\HU.gph" "C:\Users\wvanlaer\Dropbox\Doctoraat\Artikel sparen\Stata\IE.gph" "C:\Users\wvanlaer\Dropbox\Doctoraat\Artikel sparen\Stata\IT.gph" "C:\Users\wvanlaer\Dropbox\Doctoraat\Artikel sparen\Stata\NL.gph" "C:\Users\wvanlaer\Dropbox\Doctoraat\Artikel sparen\Stata\PT.gph" "C:\Users\wvanlaer\Dropbox\Doctoraat\Artikel sparen\Stata\SE.gph" "C:\Users\wvanlaer\Dropbox\Doctoraat\Artikel sparen\Stata\SI.gph" "C:\Users\wvanlaer\Dropbox\Doctoraat\Artikel sparen\Stata\SK.gph" "C:\Users\wvanlaer\Dropbox\Doctoraat\Artikel sparen\Stata\UK.gph"
    graph save Graph "C:\Users\wvanlaer\Dropbox\Doctoraat\Artikel sparen\Stata\All_countries.gph" 
    I presume there is a more efficient way of doing this, using loops but can't figure out how to do this exactly.
    Can someone give a hand?

    Thanks,

    W.

  • #2
    Hi Will,
    this code should serve your purpose.

    Code:
    local countries "AT BE BG"
    local cname "Austria Belgium Bulgaria"
    foreach cy of local countries {
        gettoken cn cname : cname
        line savings_rate year if cid=="`cy'", xtitle("") ytitle("") ///
            title("`cn'") name("`cy'")
    }
    gr combine `countries'
    graph save Graph "C:\Users\wvanlaer\Dropbox\Doctoraat\Artikel sparen\Stata\All_countries.gph"

    However, you might to consider to use -by()-

    Code:
    line savings_rate year, xtitle("") ytitle("") by(cid)
    Raffaele

    Comment


    • #3
      Don't loop at all -- is my advice.

      Consider this strategy

      Code:
      gen country = ""
      replace country = "Austria" if cid == "AT"
      * and so on
      
      line savings rate year, by(country) xtitle("") ytitle("")
      Clearly there is a bit of work there fixing the country names into a new variable, but the pay-off with by() is worthwhile.

      That said, 19 graphs combined are a stretch. Consider

      1. whether alphabetic order best satisfies your purpose.

      2. whether if comparison between savings and rate is the issue, showing the difference savings - rate as a new variablewould work better.

      3. if yes to 2 then group countries as groups of 5, 5, 5, 4 to get a four panel graph that is likely to make comparisons easier.

      EDIT: Raffaele made several similar points.

      Comment


      • #4
        Originally posted by Raffaele Grotti View Post
        Hi Will,
        this code should serve your purpose.

        Code:
        local countries "AT BE BG"
        local cname "Austria Belgium Bulgaria"
        foreach cy of local countries {
        gettoken cn cname : cname
        line savings_rate year if cid=="`cy'", xtitle("") ytitle("") ///
        title("`cn'") name("`cy'")
        }
        gr combine `countries'
        graph save Graph "C:\Users\wvanlaer\Dropbox\Doctoraat\Artikel sparen\Stata\All_countries.gph"

        However, you might to consider to use -by()-

        Code:
        line savings_rate year, xtitle("") ytitle("") by(cid)
        Raffaele
        Hey Raffaele,

        Thanks for your reply.
        I have tried your suggestion and I have 3 remarks/questions:
        • I get an error message saying: "option / not allowed". Could that be due to the fact that you have "///" after
          Code:
          yttile("")
          ? However, if I simply remove the "///" it doesn't work either. What is wrong with the syntax?
        • Could I subsitute
          Code:
          local countries "AT BE BG .."
          with
          Code:
          local countries levelsof cid
          ?
        • What is the exact use of "gettoken"? I looked it up and understand its general use, but could you briefly explain how it applies here?
        Thanks and enjoy the weekend,

        W.

        Comment


        • #5
          Hi,
          first of all let me say that the use of - by()- is still the best solution as also Nick pointed out

          Concerning your remarks:
          1. I don't think it is due to "///". In #4 you typed -yttitle- instead of -ytitle-, so I suggest you to check your code.

          2. Yes, you can use -levelsof- but you have to use it in the correct way:
          Code:
          levelsof cid, local(countries)

          3. Basically, gettoken splits your string (or list of element) in tokens.
          In this case we have a string called "cname" as follows: "Austria Belgium Bulgaria ..."
          In the first iteration of the loop, gettoken cn cname : cname takes the first token out from "cname" and stores it in "cn"
          Thus, "cn" contains now "Austria" while "cname" contains now only "Belgium Bulgaria"
          In the second iteration of the loop "cn" will contain "Belgium" while "cname" only "Bulgaria"
          I hope I've been clear enough.

          Note, however, that you will have problems in cases where the name of the country is a composite name, such as "United Kingdom"
          This is another good reason to prefer the strategy suggested by Nick!

          A work around for this specific case could be the following:

          Code:
          local countries "AT BE BG UK IT" // or levelsof cid, local(countries)
          local cname "Austria Belgium Bulgaria United Kingdom Italy"
          foreach cy of local countries {
              gettoken cn cname : cname
              if "`cy'"=="UK" {
                  gettoken cn cname : cname
                  local cn "United Kingdom"
              }
              line savings_rate year if cid=="`cy'", xtitle("") ytitle("") ///
                  title("`cn'") name("`cy'")
          }

          Best,
          Raffaele

          Comment


          • #6
            Originally posted by Nick Cox View Post
            Don't loop at all -- is my advice.

            Consider this strategy

            Code:
            gen country = ""
            replace country = "Austria" if cid == "AT"
            * and so on
            
            line savings rate year, by(country) xtitle("") ytitle("")
            Clearly there is a bit of work there fixing the country names into a new variable, but the pay-off with by() is worthwhile.

            That said, 19 graphs combined are a stretch. Consider

            1. whether alphabetic order best satisfies your purpose.

            2. whether if comparison between savings and rate is the issue, showing the difference savings - rate as a new variablewould work better.

            3. if yes to 2 then group countries as groups of 5, 5, 5, 4 to get a four panel graph that is likely to make comparisons easier.

            EDIT: Raffaele made several similar points.
            OK, I have also tried this method and it indeed is a bit more straightforward.
            Just one question with regards to the axes: now, only the graphs on the left show values for the y-axis, and only the bottom graphs show values for the x-axis. How can I counter this?

            Comment


            • #7
              Originally posted by Raffaele Grotti View Post
              Hi,
              first of all let me say that the use of - by()- is still the best solution as also Nick pointed out

              Concerning your remarks:
              1. I don't think it is due to "///". In #4 you typed -yttitle- instead of -ytitle-, so I suggest you to check your code.

              2. Yes, you can use -levelsof- but you have to use it in the correct way:
              Code:
              levelsof cid, local(countries)

              3. Basically, gettoken splits your string (or list of element) in tokens.
              In this case we have a string called "cname" as follows: "Austria Belgium Bulgaria ..."
              In the first iteration of the loop, gettoken cn cname : cname takes the first token out from "cname" and stores it in "cn"
              Thus, "cn" contains now "Austria" while "cname" contains now only "Belgium Bulgaria"
              In the second iteration of the loop "cn" will contain "Belgium" while "cname" only "Bulgaria"
              I hope I've been clear enough.

              Note, however, that you will have problems in cases where the name of the country is a composite name, such as "United Kingdom"
              This is another good reason to prefer the strategy suggested by Nick!

              A work around for this specific case could be the following:

              Code:
              local countries "AT BE BG UK IT" // or levelsof cid, local(countries)
              local cname "Austria Belgium Bulgaria United Kingdom Italy"
              foreach cy of local countries {
              gettoken cn cname : cname
              if "`cy'"=="UK" {
              gettoken cn cname : cname
              local cn "United Kingdom"
              }
              line savings_rate year if cid=="`cy'", xtitle("") ytitle("") ///
              title("`cn'") name("`cy'")
              }

              Best,
              Raffaele
              Thanks for your quick and clear response.

              Comment


              • #8
                #5 Consider

                Code:
                . sysuse auto
                (1978 Automobile Data)
                
                . scatter mpg weight, by(rep78)
                
                . h by option
                
                . scatter mpg weight, by(rep78, xrescale)
                The xrescale suboption insists on separate scales. I don't know a way to insist on explicit scales, but identical. If your x range is identical, you may be OK.

                Comment


                • #9
                  Originally posted by Nick Cox View Post
                  #5 Consider

                  Code:
                  . sysuse auto
                  (1978 Automobile Data)
                  
                  . scatter mpg weight, by(rep78)
                  
                  . h by option
                  
                  . scatter mpg weight, by(rep78, xrescale)
                  The xrescale suboption insists on separate scales. I don't know a way to insist on explicit scales, but identical. If your x range is identical, you may be OK.
                  This worked. Thanks for the help!

                  Comment

                  Working...
                  X