Announcement

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

  • Foreach loop looses local (using macro as commands)

    Dear Stata Community,

    I am quite desperate in need of your wisdom and user power. I have written an ado that is supposed to give the user a detailed overview of every value label in the dataset. Therefore I wrote loops that goes over the whole dataset and each value gathering label information. Clearly, depending on the amount of variables and value label those loops can take their time. Thus, I tried to be smart and was seeking to enhance the processing time by using forvalue loops instead of foreach loops (z is the amount of values in a variable)
    Code:
    (forvalue x = 1/z)
    The difficulty is that some variables can contain only one value and therefore the forvalue loop would result in an error because Stata cannot execute
    Code:
    forvalue x = 1/1
    Fortunately, the foreach loop is able to loop over single numbers by typing
    Code:
    foreach x of numlist 1/z
    . Now, if z would be 1 the loop would be executed without an error. So I thought instead of writing "if commands" that control for z being higher than one and to duplicate the following syntax I used a macro to manipulate the loop command (I am using tempnames for z and loop_type and a lot of other locals in my ado thats why there are so many quotation marks):

    Code:
    foreach var of varlist _all {
       
        syntax ...
    
            if ``z'' == 1 {
              local `loop_type' = `"foreach x of numlist ``z''"'
            }
            else {
              local `loop_type' = `"forval x = ``z''"'
            }
            ``loop_type''/``z'' {
    
              syntax...
    
             }
         syntax...
    }
    The strange thing is that this code does not work while a version only containing a foreach loop just runs fine. Using the trace option I found out that the first foreach loop which runs over all variables seems to loose the variable stored in `var' during one of the loops. At first I thought I missed a curled bracket or added one by accident, but a comparison to the earlier working version with a text editor showed me that there are no extra or missing brackets and Stata does not give me the too few ({ error.

    I assume that somehow the execution of the macros lead temporary to a bracket closing the foreach var of varlist _all loop and therefore terminating the content of `var' But I really don't know if this is the case and to look at the syntax and not seeing any error drives me nuts.

    Maybe some more experienced user or someone from StataCorp can help me out here and has an idea what is happening.

    Best wishes and thank you very much in advance,
    Malte

    PS: For more clarity on the subject I attached the whole syntax.
    Attached Files

  • #2
    The difficulty is that some variables can contain only one value and therefore the forvalue loop would result in an error because Stata cannot execute
    Code:
    forvalue x = 1/1
    My experience says this is not the case.
    Code:
    . forvalue x = 1/1 {
      2. di "Here it is: " `x'
      3. }
    Here it is: 1
    Have I misunderstood something?

    Comment


    • #3
      Hi William,

      you are absolutely right. I just checked and of course no error results.
      I don't know why I had in mind that such loop would not work but it kept me effectivly away from trying just the simplest solution. Thank you very much!

      However, maybe someone can still bring some light into the macro execution question because even if my syntax above is unecessary for performance purpose it still should work, right?

      Best wishes,
      Malte

      Comment


      • #4
        Perhaps if you were to create and share a simple, reproducible example of code that fails to run, readers could work with it to isolate the problem. But as it stands now, you are expecting introspection alone to solve a complex problem, and readers here are often reluctant to express answers to such problems without being able to verify their answer in Stata. Expecting the reader to create an example that fails in the same way as your code, and then find a solution to the problem, is overly optimistic,

        This is especially true given that the solution to reaching your objective was to correct a misunderstanding of yours about value lists. In the back of my mind, at least, is the thought that the problem with your complicated code reflects some other misunderstanding that I would be unlikely to make in trying to create an example to test. And further, a misunderstanding that you might discover on your own were you to spend the time simplifying your code enough to abstract the problem into a small reproducible example.

        The more you help others understand your problem, the more likely others are to be able to help you solve your problem.

        Comment


        • #5
          I'd also note that you might find relevant the official commands -uselabel- or -labelbook-, if you have not already considered them.

          Comment


          • #6
            Also see labutil, labutil2 (both from SSC) and related existing user-written commands. Chances are you are re-inventing the wheel.

            Looking at your code I notice that you are defining temporary names for locals. This is unnecessary as locals exist only within the scope of your do or ado-file and it makes the code much harder to read and debug. The problem might be easier to spot if you get rid of all those unnecessary compound locals.

            Best
            Daniel

            ​​​​​​​

            Comment

            Working...
            X