Announcement

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

  • Loop and locals

    Hi,

    I have the following dataset:


    Code:
    * Example generated by -dataex-. To install: ssc install dataex
    clear
    input float(ID exit income_2014 income_2015 income_2016)
    1 2013 25000 27000 28000
    2 2014 30000 32000 33000
    3 2015 28000 29000 30000
    4 2013 26000 28000 29000
    end
    I want to create a loop to generate variables that show one year after the exit year, two years after the exit rate, and so on.
    For example, if my exit=2013, I would want to create variables t1 that shows the income in 2014, t2 that shows income in 2015, and so on.

    So far I have the following, but for some reason it does not work

    Code:
    gen t1 = .
    gen t2 = .
    gen t3 = .
    gen t4 = .
    gen t5 = .
    
    foreach t in 2003/2015 {
        * Calculate the year after finding a job
        local job_year_t1 = `t' + 1
        local job_year_t2 = `t' + 2
        local job_year_t3 = `t' + 3
        local job_year_t4 = `t' + 4
        local job_year_t5 = `t' + 5
        
        * Populate income variables for each year after finding a job
        replace t1= income_`job_year_t1' if exit == `t'
        replace t2= income_`job_year_t2' if exit == `t'
        replace t3= income_`job_year_t3' if exit == `t'
        replace t4= income_`job_year_t4' if exit == `t'
        replace t5= income_`job_year_t5' if exit == `t'
    }

  • #2
    This task is much easier to do in long layout, and does not require any loops.

    Code:
    preserve
    
    isid ID
    reshape long income_, i(ID) j(year)
    gen latency = year - exit if year > exit
    drop year exit
    drop if missing(latency)
    rename income_ income_job_year_
    reshape wide income_job_year_, i(ID) j(latency)
    tempfile holding
    save `holding'
    
    restore
    merge 1:1 ID using `holding', assert(match master) nogenerate

    Comment


    • #3
      Originally posted by Clyde Schechter View Post
      This task is much easier to do in long layout, and does not require any loops.

      Code:
      preserve
      
      isid ID
      reshape long income_, i(ID) j(year)
      gen latency = year - exit if year > exit
      drop year exit
      drop if missing(latency)
      rename income_ income_job_year_
      reshape wide income_job_year_, i(ID) j(latency)
      tempfile holding
      save `holding'
      
      restore
      merge 1:1 ID using `holding', assert(match master) nogenerate
      Makes sense, thank you so much, it works great! Could you please what part of my code is wrong? I get the following error:
      income_1.994044665012407 invalid name

      Comment


      • #4
        The root cause of the problem is -foreach t in 2003/2015-. You probably think this iterates t over values 2003 through 2015. But it doesn't. To do that, you need -forvalues t = 2003/2015-.

        Here's what -foreach t in 2003/2015- does. Stata looks at what follows -in- and treats it as a list of tokens. It finds one token: 2003/2015. So it sets t = 2003/2015, which it evaluates as t = .994044665012407.

        The error propagates from there: local job_year_t1 is now 1.994044665012407, and local job_year_t2 is 2.994044665012407, etc. Finally, things come crashing down when we get to -replace t1= income_`job_year_t1' if exit == `t'-, which after macro substitution becomes:

        Code:
        replace t1= income_1.994044665012407 if exit == .994044665012407
        income_1.994044665012407 is, of course, not a legal variable name because it contains a decimal point. (And it is, of course, not remotely what you intended in any case.)

        Comment


        • #5
          Originally posted by Clyde Schechter View Post
          The root cause of the problem is -foreach t in 2003/2015-. You probably think this iterates t over values 2003 through 2015. But it doesn't. To do that, you need -forvalues t = 2003/2015-.

          Here's what -foreach t in 2003/2015- does. Stata looks at what follows -in- and treats it as a list of tokens. It finds one token: 2003/2015. So it sets t = 2003/2015, which it evaluates as t = .994044665012407.

          The error propagates from there: local job_year_t1 is now 1.994044665012407, and local job_year_t2 is 2.994044665012407, etc. Finally, things come crashing down when we get to -replace t1= income_`job_year_t1' if exit == `t'-, which after macro substitution becomes:

          Code:
          replace t1= income_1.994044665012407 if exit == .994044665012407
          income_1.994044665012407 is, of course, not a legal variable name because it contains a decimal point. (And it is, of course, not remotely what you intended in any case.)
          Oh wow, I understand now. Thank you so much, I was so confused!!

          Comment

          Working...
          X