Announcement

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

  • Using a global macro with "foreach i of num ... "

    Hello all,

    I have been working on a dataset that I am constantly expanding, adding new variables daily. I have some loops as well, where I have used "foreach" in some cases. One of my commands is like "foreach i of num 108/1 {" and does the job fine. The problem is I have a command like this in many parts of my do file, and the max value of the numlist range sometimes shall be 107 (so n-1). Now, everytime I add more variables, say 40 new columns, my previous command shall become "foreach i of num 148/1 {", but I have been doing this by hand (changing every value from say 108 to 148) everytime I added variables in every loop that is like that. This is of course not efficient. I have been wondering about using macros here, something like:

    . global x = 108

    . foreach i of num $x/1 {


    But also (when I need n-1):

    . foreach i of num $x-1/1 {


    But this does not work, STATA reporting "invalid numlist".


    Can someone help? I am quite a novice to loops and macros in general. Thanks in advance, regards.

    Andrea
    Last edited by Andrea Berni; 12 Aug 2020, 13:28.

  • #2
    Well you don't provide many specifics, so I can only offer you some general advise. Instead of looping over a numerical counter, why not just loop over the list of variables themselves. You know, -foreach v of varlist whatever { …- where whatever can be the variables themselves spelled out (including using wildcards), or can be something that you have previously stored in a macro.

    If there is some reason that isn't practical, then stop using a global macro for x. Local macros are safer, and in this case also more convenient. When you need n-1, you can do that as -foreach I of numlist `=`x'-1'/1 { …- if you start with -local x = 108-.

    I'll spare you my long rant about the dangers of global macros. Suffice it to say that they are an unsafe programming practice and should only be used when there is no alternative. For storing a number, local macros work just as well.

    Comment


    • #3
      Thank you for your reply. I am sorry I have provided little information, you are quite right. Anyway, I have managed to use global macros in my loops. The reason why I do not want to use local macros is because I do not always want to run the whole do in one click, so I prefer using a global macro. I will be careful about using them, thanks again for warning me and providing some useful information about the working of local macros as well.
      Some might be curious, these are my new commands now (used repeatedly through the do file):

      . global x = 108

      . foreach i of num `=$x'/1 { ...
      . foreach i of num `=$x-1'/1 { ...

      Comment


      • #4
        The reason why I do not want to use local macros is because I do not always want to run the whole do in one click, so I prefer using a global macro.
        Yes, people say that a lot. It's a bad reason because:

        1. The easy way to work with locals when you only want to run part of the code is to comment out everything between the line that initializes the local macro and the part of the code you want to run In modern Stata, since at least version 13, maybe earlier that's just one-click after highlighting the stuff to comment out. And then another one-click operation to uncomment it when you're done.

        2. You will probably get away with using global macros for a long time before you get bitten. But when you do get bitten, the bug will be nasty and very difficult to find, and may also be very difficult to fix. If it ever happens to you, I am quite sure you will never want to have that experience again.

        By the way, maybe $x was just for illustration, but if you are using names like that, then you are definitely not being careful. If you insist on using global macros, pick names that look like hard passwords--names that nobody else is likely to have used. Because if your macro has the same name as some other global macro anywhere along the call stack, you are in trouble.

        Comment

        Working...
        X