Announcement

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

  • Creating a second new variable based on the first new variable in a loop

    I am attempting to create a loop to generate a new variable, but also need to create a second new variable based on the first new variable within that loop.

    Specifically, I want to create and replace values for a new variable called 'med_x', where x represents a time-point that can equal values 1-20; the values of 'med_x' will be based on when the medication starts and stops in relation to 'month_y' and 'month_z', where y= x*3 and z = (x*3)-3. I could of course do this by hand by writing code out for values 1-20, but I know there is an easier way to code the logic. Any help figuring this out would be appreciated!

    Here is an example if I were to code one time-point at a time:

    gen med_4 = 1 if start_date_master <= month_12 & stop_date_master >= month_12
    replace med_4 = 1 if start_date_master <= month_12 & stop_date_master < month_12 & stop_date_master > month_9

    I am not sure if this requires a double loop (or loop within a loop), or if there is an easier process. I've also tried creating two local variables to reference within one loop, but either get no error (but no variable is produced), or an "invalid syntax" error. This is my latest attempt:

    Code:
    local timepoint 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
    foreach x of local timepoint {
        local month_period timepoint*3
        foreach y of local month_period {
        gen med_`x' = 1 if start_date_master <= month_`y' & stop_date_master >= month_`y'
        replace med_`x' = 1 if start_date_master <= month_`y' & stop_date_master < month_`x' & stop_date_master > month_`y'
         } 
    }
    Here the error code I get is "invalid syntax."

    Thanks in advance!!

  • #2
    I really don't understand what you want to do; I can't follow your explanation. But I can tell you where your syntax error is coming from.

    Code:
    local month_period timepoint*3
    while legal syntax, is causing your -gen med_`x'...- command to have a syntax error.

    When you say -local month_period timepoint*3-, Stata stores the string "timepoint*3" in local macro (not variable) x. The -foreach y- loop (which isn't really a loop since local month_period contains only a single token and so this "loop" has only a single iteration) then sets local macro y equal to the string "timepoint*3". So your -gen med_`x' = ...- command is expanded to read
    Code:
    gen med_`x' = 1 if start_date_master <= month_timepoint*3 & stop_date_master >= month_timepoint*3
    Since there is no variable named month_timepoint in play, the conjuncts in the -if- condition are both syntax errors.

    So you need something more like this.
    Code:
    foreach x of numlist 1(1) 20 {
        local y = `x'*3
        gen med_`x' = 1 if start_date_master <= month_`y' & stop_date_master >= month_`y'
        replace med_`x' = 1 if start_date_master <= month_`y' & stop_date_master < month_`x' & stop_date_master > month_`y'
    }
    The = in the revised definition of local macro y tells Stata not to put the string "`x'*3" into local macro y but rather to evaluate the expression `x'*3 and store the result there instead. This then makes month_`y' a variable name in the -gen- and -replace- commands and will relieve you of your syntax error.

    Note that the pointless -foreach y- loop has been eliminated, and the -foreach x- loop has been simplified by looping over a -numlist- from 1 to 20.

    As I don't know what you are trying to calculate here, I don't know if this code will calculate what you want. But it deals with your syntax error.

    Comment


    • #3
      Dear Clyde,

      Thank you so much for your quick response! Sorry for the confusion- I think what may have contributed to it was my failure to include "z" in the code.

      In any case, what I couldn't figure out was how to tell Stata to evaluate the expression and store the result, rather than read the term as a string. Thank you for clarifying that.

      For reference, the final code that ending up working and getting me what I needed was:

      Code:
      foreach x of numlist 1(1) 20 {
          local y = `x'*3
          local z = (`x'*3)-3
          gen med_`x' = 1 if start_date_master <=month_`y' & stop_date_master >=     month_`y'
          replace med_`x' = 1 if start_date_master <= month_`y' &     stop_date_master < month_`y' & stop_date_master > month_`z'
          }
      Thanks again!

      Comment

      Working...
      X