Announcement

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

  • Setting an alternating number count within a loop

    Hello, I am attempting to create a loop that goes through a sequence of variables. There are three distinct variable sets: the first set has numeric suffices running from 1-2 (containing the acronym PSH), the second 1-4 (ES), and the third 1-2 (TH) once again. I am renaming them all to Address2-9 (it's basically concatenating three address parts into one complete address field). I want to set an alternating number count within the loop that would go only up to 2 for the first and third group of variables and then up to 4 for the second.
    I devised the below loop as a general example. although it does not work:
    Code:
    . loc i=2
    
    . loc k=1
    
    . foreach j in PSH ES TH {
      2. g Address`i' = Serv`j'Loc`k'+", "+Serv`j'Loc`k'1+", NJ "+Serv`j'Loc`k'2 if !missing(Serv`j'Loc`k')
      3. drop Serv`j'Loc`k' Serv`j'Loc`k'1 Serv`j'Loc`k'2
      4. loc ++i
      5. loc ++k
      6. }
    (49 missing values generated)
    (51 missing values generated)
    ServTHLoc3 not found
    r(111);
    
    end of do-file
    
    r(111);

  • #2
    I could not understand your explanation of the problem and description of the data set. After several readings I still don't get what your data set looks like, nor what the result you seek is. I think it would be helpful if you were to post an example of your data set, using the -dataex- command, of course, and then show another example of what you would like the results from that example to look like. I think that would work better than explaining it in words.

    If you are running version 15.1 or a fully updated version 14.2, -dataex- is already part of your official Stata installation. If not, run -ssc install dataex- to get it. Either way, run -help dataex- to read the simple instructions for using it. -dataex- will save you time; it is easier and quicker than typing out tables. It includes complete information about aspects of the data that are often critical to answering your question but cannot be seen from tabular displays or screenshots. It also makes it possible for those who want to help you to create a faithful representation of your example to try out their code, which in turn makes it more likely that their answer will actually work in your data.



    When asking for help with code, always show example data. When showing example data, always use -dataex-.

    Comment


    • #3
      It seems that you have eight commands of which the first is (something like)

      Code:
      g Address2 = ServPSHLoc1 + ", " + ServPSHLoc11 + ", NJ " + ServPSHLoc12 if !missing(ServPSHLoc1)
      Note that I have used more spaces than you did.

      Unexciting though the code will look, I would just keep going with the other seven, varied suitably.

      As you have an irregular structure to your data, you won't tame it with any simple loop.

      The losses and gains here are simple at one level:

      1. Time spent writing very tricky code isn't well spent if there is a quicker and simpler way to do it. (A purpose of computing is to save time, not spend it.)

      2. Writing tricky code concisely is no gain if it's prone to bugs, hard for you to understand later, and even harder for others reading your code to understand --- and borrow, modify, or debug, which others often have to do. (Code has to be read, as well as written.)

      Wanting to learn about loops in any language is fine, but if you keep going in Stata there will be plenty of other problems where they help a lot.

      Yet another answer is that perhaps the variable names should be fixed first. Then the loop may seem much easier.
      Last edited by Nick Cox; 25 Apr 2019, 04:34.

      Comment


      • #4

        I think this is a loop answer to what you asked, but it's not simpler than 8 plain statements one after the other.


        Code:
        loc u "PSH"
        loc k = 1
        
        forval j = 2/9 {
            if `j' == 4 {
                 local u "ES"
                 local k = 1
            }
            else if `j' == 8 {
                local u "TH"
                local k = 1
            }    
            g Address`j' = Serv`u'Loc`k' + ", " + Serv`u'Loc`k'1 + ", NJ " + Serv`u'Loc`k'2 if !missing(Serv`u'Loc`k')
            loc ++k
        }
        For local names in Stata code (and this is a note to myself as much as anybody else) I like to respect common conventions, including my own, so for example

        a is an intercept
        b is a slope
        i loops over observations (rows) (and is always a counter)
        j loops over variables (columns) (ditto)
        k could be another counter
        p is the number of predictors
        t might index time
        v loops over variable names
        x is a predictor
        X is a bundle of predictors
        y is a response

        Often, naturally, names should be longer and self-explanatory.

        I always follow StataCorp convention over the name touse. For informal examples not in serious code, I reach for foo sometimes (old computing convention) and frog, toad and newt (just names that appeal as short and unlikely to clash with most people's serious use, absent many zoologists here.

        You wouldn't have to look far in my code to find exceptions. And although it's personally helpful to have rules for yourself, it may be at best irritating to be told to follow someone else's!

        Any way, that is why I didn't use all the names in #1 as you did.
        Last edited by Nick Cox; 25 Apr 2019, 05:03.

        Comment


        • #5
          Thank you so much, that worked perfect.

          Comment

          Working...
          X