Announcement

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

  • Loop over multiple arrays via foreach

    Hello together!

    trying now since a few hours to fix my problem - I am not able to come up with an adequate solution. I need your help / advise!

    I would like to run the blow shown STATA code. My problem is that it will only work for the first observation (example1 @ 1999 and example2 @ 2005).

    How can I work with multiple entries? Any ideas?

    Code:
    tsset ID YEAR
    
    local example1 1999
    local example1 2000
    local example2 1999
    local example2 2005
    
    foreach i in numlist 100005 {                  
    local t `example`i''
    replace  TEST_variable  = 10 if ID == "`i'" & YEAR == `t'
    }
    Thank you for your help!

    Konstantin

  • #2
    Your command
    Code:
    local t `example`i''
    first becomes, when the value of `i' is substitute4d
    Code:
    local t `example100005'
    and the, since there is no local `example100005', becomes
    Code:
    local t
    so that the next command becomes
    Code:
    replace  TEST_variable  = 10 if ID == "`100005'" & YEAR ==
    which is a syntax error.

    Instead of giving code that does not work, leaving us to guess what it intended to do, you will do better follow the advice in the Statalist FAQ on how to present your question. Show us sample data show us what you want the results to be.

    Comment


    • #3
      Hello William.

      Thank you for your fast response.

      I tried to simplify the code and made the mistake you mentioned.

      The code should be as shown below:

      Code:
      tsset ID YEAR local example1 1999 local example1 2000 local example2 1999 local example2 2005 foreach i in numlist 1 2 { local t `example`i'' replace TEST_variable = 10 if ID == "`i'" & YEAR == `t' }
      If I write it in that way it helps not:

      Code:
      tsset ID YEAR local example1 1999 local example1 2000 local example2 1999 local example2 2005 foreach i in numlist 1 1 2 2 { local t `example`i'' replace TEST_variable = 10 if ID == "`i'" & YEAR == `t' }

      The code itself works. However, it checks only for example 1 and the year 1999. The year 2000 is ignored.

      I would like to change the Variable "Test_variable" into 10 if the ID is "1" or "2" and respective year ("1999", "2000", "2005").
      ID YEAR TEST_Variable
      1 1999 10 <--- this works
      1 2000 10 <-- this works not
      1 2001 .
      1 2002 .
      2 1999 10
      <--- this works
      2 2000 .
      2 ... .
      2 2005 10
      <-- this works not
      ... ... ...
      I hope it makes my problem easier to understand. Thank you!

      Konstantin

      Comment


      • #4
        If I understood your problem correctly, then there is no need for a loop. Just try the code below and see whether it gives you the desired results:
        Code:
        capture drop  TEST_variable // drop the variable in case it already exists
        gen TEST_variable = . // create an empty variable
        replace TEST_variable = 10 if inlist(ID, 1,2) & inlist(year,1999,2000,2005) // set value to 10 if id is equal to 1 or 2 and year is equal to 1999, 2000 or 2005
        I doubt that your original code runs fine.
        Instead of
        Code:
        local example1 1999
        local example1 2000 // you overwrite the previous macro definition, so only 2000 is in the macro
        local example2 1999
        local example2 2005 // same as above
        foreach i in numlist 1 1 2 2 { // instead of "in" you need to use "of" otherwise the word "numlist" is the first content of the macro 'i'.
        local t `example`i''
        replace TEST_variable = 10 if ID == "`i'" & YEAR == `t' // the " " around the 'i' will work only if the ID variable is a string variable.
        }
        You would have do to something like the next code if you still want to use a loop:
        Code:
        local
        forvalues i =1/2{
        foreach t of numlist 1999 2000 2005{
        replace test = 10 if id ==`i' & year==`t'
        }
        }

        Comment


        • #5
          This is hard to follow. There is no data example; there is some unnecessary code; and your use of foreach apparently does not bite you but is ill advised, namely that of numlist not in numlist is the recommended syntax.

          This seems to be the heart of the matter, but try as hard as I can I can't reproduce the error you report.

          Code:
          clear
          input str1 ID    YEAR    
          1    1999    
          1    2000    
          2    1999    
          2    2005    
          end
          
          gen TEST = .
          
          * !!! note: each second definition just overwrites the first
          local example1 2000
          local example2 2005
          
          foreach i of numlist 1 1 2 2 {                
              local t `example`i''
              replace TEST = 10 if ID == "`i'" & YEAR == `t'
          }
          
          list
          
               +------------------+
               | ID   YEAR   TEST |
               |------------------|
            1. |  1   1999      . |
            2. |  1   2000     10 |
            3. |  2   1999      . |
            4. |  2   2005     10 |
               +------------------+
          EDIT: Overlaps with the helpful post of Sven-Kristjan Bormann

          It's true that you don't need loops for what you are doing in your post, but I am going to guess that your real data are much more extensive.
          Last edited by Nick Cox; 31 Jan 2020, 06:24.

          Comment


          • #6
            Svem-Kristjan Bormann and Nick Cox, thank you. This works.

            I have one further question. Is there a way to give a second definition?

            The years are different for each ID (and sometimes more than 1). That is why I need a loop :-(

            Comment


            • #7
              I read your problem as editing data for certain individuals and certain years. It's hard to advise in abstraction, but that sounds like a merge problem to me. It doesn't sound like a problem where you write code to loop over identifiers and years and specify new values.

              In some cases it's not outrageous to edit the data in the Editor so long as you keep a log.

              Comment

              Working...
              X