Announcement

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

  • Loop with "starting values"

    Good evening to everyone,

    I would like to run a loop where a parameter that takes an initial value I decided is then updated at the end of the loop to take another value I estimated, and then the loop restarts until the difference between the initial condition and the estimated parameter is negligible. This is what I've tried:

    Code:
    reg y l k i.sector_id i.t
    scalar b_0_star_LP = _b[k]  /* This guy is the starting value */
    
    forvalues i = 0/100{
        gen omega_LP_`i' = phi_LP -  b_`i'_star_LP*k
        gen omega_h_LP_`i' = phi_h_LP -  b_`i'_star_LP*k
        gen lead_omega_LP_`i' = F.omega_LP_`i'
        npregress kernel lead_omega_LP_`i' omega_h_LP_`i'
        predict E_omega_LP_`i'
        ivregress gmm lead_phi_LP lead_k (E_omega_LP_`i' = k i)
        scalar  b_`i+1'_star_LP = _b[lead_k]
        if b_`i+1'_star_LP - b_`i'_star_LP < 0.00000001
        break
    }
    I get the error:

    Code:
    { required
    After the GMM is run... I don't understand where should I put the bracket... Could someone help me?

    Thanks in advance for the help!

  • #2
    The problem is with your if statement. This line needs open and close brackets and a body.
    Code:
    if b_`i+1'_star_LP - b_`i'_star_LP < 0.00000001{
    break
    }

    Comment


    • #3
      Originally posted by Daniel Schaefer View Post
      The problem is with your if statement. This line needs open and close brackets and a body.
      Code:
      if b_`i+1'_star_LP - b_`i'_star_LP < 0.00000001{
      break
      }
      Thank you Daniel! Effectively, now I can complete the first iteration with this code:

      Code:
      reg y l k i.sector_id i.t
      scalar b_0_star_LP = _b[k] /* This guy is the starting value */
      
      
      forvalues i = 0/100{
          gen omega_LP_`i' = phi_LP -  b_`i'_star_LP*k
          gen omega_h_LP_`i' = phi_h_LP -  b_`i'_star_LP*k
          gen lead_omega_LP_`i' = F.omega_LP_`i'
          npregress kernel lead_omega_LP_`i' omega_h_LP_`i'
          predict E_omega_LP_`i'
          ivregress gmm lead_phi_LP lead_k (E_omega_LP_`i' = k i)
          scalar  b_`i+1'_star_LP = _b[lead_k]
          scalar delta_`i' = b_`i+1'_star_LP - b_`i'_star_LP
          if delta_`i' < 0.00000001{
          break
          }
      }
      However, I get the following error after the GMM in the second iteration...

      Code:
      b_2_star_LP not found
      I can't see why, even in this case... Thanks a lot anyway!!

      Comment


      • #4
        Hi Matteo,

        It might be easier to help you debug this if you provide an example dataset with dataex. That said, when you create the b_`i+1'_star_LP scalar, you should put the +1 outside of the quotes: b_`i'+1_star_LP.

        This may be illustrative:
        Code:
        . forvalues i = 0/4{
          2.     di `i+1'
          3. }
        0
        1
        2
        3
        4
        
        . forvalues i = 0/4{
          2.         di `i' + 1
          3. }
        1
        2
        3
        4
        5
        
        . 
        end of do-file

        Comment


        • #5
          Apologies, the change I suggest above is not quite right. There may be a way to inline this with your variable declaration, but I would suggest for simplicity's sake you just create a local to temporarily store the added value instead.

          Code:
          local i_plus_one = `i' + 1
          scalar b_`i_plus_one'_star_LP = _b[lead_k]
          Last edited by Daniel Schaefer; 02 Jun 2022, 12:37. Reason: Edited for clarity

          Comment


          • #6
            There is a way to inline this kind of calculation:

            Code:
            scalar b_`=`i'+1'_star_LP = _b[lead_k]

            Comment


            • #7
              Originally posted by Daniel Schaefer View Post
              Apologies, the change I suggest above is not quite right. There may be a way to inline this with your variable declaration, but I would suggest for simplicity's sake you just create a local to temporarily store the added value instead.

              Code:
              local i_plus_one = `i' + 1
              scalar b_`i_plus_one'_star_LP = _b[lead_k]
              Thanks a lot Clyde, and Daniel! Indeed, now it works! I've learned a lot from this!

              I've seen from a previous post of Clyde that there's another mistake in my loop: I saw, indeed, that in Stata, a break statement doesn't amount to "We're done, here", hence the loop above goes on infinitely.

              However, I saw also that
              continue, break does the trick. This loop, indeed, works (I also drop the useless variable I generated during the loop)!

              Code:
              forvalues i = 0/100{
                  local j = `i' + 1
                  gen omega_LP_`i' = phi_LP -  b_`i'_star_LP*k 
                  gen omega_h_LP_`i' = phi_h_LP -  b_`i'_star_LP*k
                  gen lead_omega_LP_`i' = F.omega_LP_`i'
                  npregress kernel lead_omega_LP_`i' omega_h_LP_`i'
                  predict E_omega_LP_`i'
                  ivregress gmm lead_phi_LP lead_k i.t (E_omega_LP_`i' = k i)
                  scalar  b_`j'_star_LP = _b[lead_k]
                  scalar delta_`j' = b_`j'_star_LP - b_`i'_star_LP
                  if delta_`j' < 0.00001{    
                  continue, break
                  }
                  else {
                  drop omega_LP_`i' omega_h_LP_`i' lead_omega_LP_`i' E_omega_LP_`i'
                  }
              }
              Code:
              
              

              Comment

              Working...
              X