Announcement

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

  • Scope of iterator variables in control structures (loops)

    Hi all,

    It appears that I have no access inside a for or while loop to variables that are declared as part of the loop construction or outside of the loop, and I cannot find any documentation using standard programming terms such as "scope" to explain how to work around. What I'd like to do is something like:

    local i = 0
    while `i' < 100 {
    if condition {
    ++`i'
    }
    else {
    local i = somefunction(`i')
    }
    }

    I can change the value of i, but when the code loops, it returns to the value set outside of the loop. same thing with forvalues{}
    Any help is appreciated

  • #2
    The evident problem here is in that Stata

    Code:
    ++`i' 
    is illegal. That is nothing to do with looping.

    If you want to bump up a local macro using ++ you use its name (don't try to deference it at the same time). Some wrong and right code here:


    Code:
    . local i = 1
    
    . ++`i'
    + is not a valid command name
    r(199);
    
    . local ++i
    
    . di "`i'"
    2
    You can access loop macros within a loop. This silly code works:

    Code:
    local i = 0
    
    while `i' < 100  {
       if `i' == 7 local i = 100
       else local ++i
      
       di "`i'"
     }


    If that doesn't answer the question, please give a specific code segment that illustrates your problem.

    Comment


    • #3
      Thanks Nick for your response,

      Your code works fine, but when I use the same technique in my situation it fails to modify the iterator

      Code:
      local i = 4432503
      while `i' < 35189702{
      if y1_mean_lag[`i'] == . & p_lag[`i'] != . {
      local this_cell_id = cell_id[`i']
      local lag_cell_id = `this_cell_id' - 100
      local j = `i' + 1

      display "count if cell_id == `lag_cell_id'"
      count if cell_id == `lag_cell_id'

      local this_N = r(N)

      if `this_N' > 0 {
      while cell_id[`j'] > `lag_cell_id' {
      local j = `j' - 1000
      }
      if cell_id[`j'] == `lag_cell_id'{
      local this_y1_mean_lag = y1_mean[`j']
      local this_y2_mean_lag = y2_mean[`j']
      local this_y3_mean_lag = y3_mean[`j']
      replace y1_mean_lag = `this_y1_mean_lag' if cell_id == `this_cell_id'
      replace y2_mean_lag = `this_y2_mean_lag' if cell_id == `this_cell_id'
      replace y3_mean_lag = `this_y3_mean_lag' if cell_id == `this_cell_id'
      }
      local ++i
      }

      }

      }

      Comment


      • #4
        Unfortunately, what's going on there is about as clear to me as some card game I've never understood (which means all of them).

        But stripping it down, I see only

        Code:
        local  ++i
        as modifying the main loop counter, so what's the grounds or evidence for saying "fails to modify"?

        The problem looks fairly bizarre: You're looping over observations (are you sure that's the only feasible approach?). There are backwards jumps of 100 and 1000 that presumably arise from some logic.




        Comment


        • #5
          I don't think I follow the code any better than Nick does. But I will point out that the -local ++i- command is inside the block controled by -if `this_n' > 0-. So i is only going to change in a situation where you end up with `this_N' > 0 from the code above that -if- block. As I don't really follow the code, and, even if I did, I have no idea what your data are like, I can't say much with confidence, but it sounds as if the problem may be that your -local ++i- command is just never being reached. Perhaps the solution to your problem is to move it outside of the -if- block?

          Comment


          • #6
            Thanks Nick and Clyde

            I had modified that code to workaround the issue, and then tried to quickly change it back to show you the trouble. Clearly I was in a hurry and missed some stuff - specifically the lines that update i outside of the if block in question. Sorry about that.

            I'm not sure what was / is going on. During an intermediate troubleshooting step I displayed some troubleshooting text, and also displayed the current value of i, which was updating as the loop progressed and then returning to the initial value every time it returned to the top of the loop even though there were no commands inside the loop to restore it to its initial value.

            It's always possible I was getting tired and misdiagnosed the issue, but it was behaving exactly as if stata was storing a global value of i and a separate local value of i.

            If I run into the trouble again I'll post some code before I change it.

            Oh... and as for what the code is supposed to do - it's complicated and doesn't really matter for this discussion... But Nick, you wanna play some poker? I don't know how to play either.

            Comment


            • #7
              All card games are a mystery to me. Stata fills that gap in my life, and some others.

              Comment

              Working...
              X