Announcement

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

  • Error in stata loop saying variable already defined.

    Hi,
    I have a bunch of IDs for which I need to replicate values for 208 weeks. The value for each week has to be the status of the ID holder which is either Derived, Transported, Listed, Not listed or Removed. So I need a value stating the status of each ID for each week. Doing it only by week is easy. However, I need the status for the IDs in the first week (week 0 ) by day. So my data should be looking in the raw form something like this.
    ID day 1 day2 day3 day4 day5 day6 day7 week1 week2 week3 week4
    status Listed Listed Listed Listed Listed Listed Derived Derived Derived Derived Derived
    However, when I run the code below, I get an error saying status1 already defined. Any ideas what I can do?
    Also I need to reshape the code below from long to wide. So when I am dealing only with weeks its easy reshape wide status i(ID) j(week), But how do I do it if I need to reshape days and week as well? Any suggestions would be appreciated.
    Code:
    forvalues a = 1/1 {
        keep if can_college == `a'
        forvalues w = 0/208 {
    if `w'==0 {
        forvalues d = 1/7{
    qui gen status`d' = .
    qui replace status`d' = 1 if !inrange(faildate_1, edate_new,remdate_new)
    qui replace status`d' = 2 if inrange(faildate_1, edate_new, remdate_new)
    qui replace status`d' = 3 if (faildate_1  >= remdate_new) & !missing(remdate_new)
    qui replace status`d' = 4 if (tdate_2 <= faildate_1 ) & !missing(tdate_2)
    qui replace status`d' = 5 if (died <= faildate_1 ) & !missing(died)
        }
    }
        else {
    qui replace status`w' = .
    qui replace status`w' = 1 if !inrange(faildate_1+ `w'*7, edate_new,remdate_new)
    qui replace status`w' = 2 if inrange(faildate_1 + `w'*7, edate_new, remdate_new)
    qui replace status`w' = 3 if (faildate_1 + `w'*7 >= remdate_new) & !missing(remdate_new)
    qui replace status`w' = 4 if (tdate_2 <= faildate_1 + `w'*7) & !missing(tdate_2)
    qui replace status`w' = 5 if (died <= faildate_1 + `w'*7) & !missing(died)
    label define status`w' 1 "Not listed" 2 "Listed" 3 "Removed" 4 "Transported" 5 "Derived"
    label value status`w' status`w'
        }
        }
        }
        keep id  status*
        reshape long status, i(id) j (week)
        save educ_plot_`a', replace
        }
    variable status1 already defined
    r(110)
    Last edited by Shalom Patole; 09 Oct 2020, 11:59.

  • #2
    Sorry the first table should be like this:
    ID Status
    1 day1 listed
    1 day2 listed
    1 day3 listed
    1 day4 listed
    1 day5 listed
    1 day6 listed
    1 day7 listed
    1 week1 listed
    1 week2 listed
    The table I have mentioned in the original post is what is expected after the reshape command is given.

    Comment


    • #3
      I can't see the immediate problem, so I just post some gratuitous advice.

      1. While debugging you don't want quite so many quietly prefixes. You may need to add more list statements to see what is going on.

      2. Once the code is firmed up you don't need so many either. If every statement inside a block is
      quietly, take that prefix one level up.

      3. This is a little bit harder to follow than it could be given some inconsistency in indenting. I used to tab 8 spaces, but now think 4 is better. Everyone should find their own rule.

      I count one unmatched brace or curly bracket
      {

      I got to this sketch of the code:

      Code:
      forvalues a = 1/1 {
          keep if can_college == `a'
          quietly forvalues w = 0/208 {
              if `w'==0 {
                  forvalues d = 1/7{
                      gen status`d' = .
                      replace status`d' = 1 if !inrange(faildate_1, edate_new,remdate_new)
                      * similar statements 
                  }
              }
              else {
                  replace status`w' = .
                  replace status`w' = 1 if !inrange(faildate_1+ `w'*7, edate_new,remdate_new)
                  * similar statements 
                  label define status`w' 1 "Not listed" 2 "Listed" 3 "Removed" 4 "Transported" 5 "Derived"
                  label value status`w' status`w'
              }
          }
      }
      
          
      keep id  status*
      reshape long status, i(id) j (week)
      save educ_plot_`a', replace
      Code:
      
      

      Comment


      • #4
        Thanks Nick,

        I have made the following changes

        Code:
        forvalues a = 0/1 {
            keep if can_college == `a'
            quietly forvalues w = 0/208 {
                if w==0{
                    forvalues d= 1/7{
                        gen status`w' = .
                        replace status`w' = 1 if !inrange(faildate_1+ `d', edate_new,remdate_new)
                        replace status`w' = 2 if inrange(faildate_1 + `d', edate_new, remdate_new)
                        replace status`w' = 3 if (faildate_1 + `d' >= remdate_new) & !missing(remdate_new)
                        replace status`w' = 4 if (tdate_2 <= faildate_1 + `d') & !missing(tdate_2)
                        replace status`w' = 5 if (died <= faildate_1 + `d') & !missing(died)
                    }
                }
               else{    
                        replace status`w' = .
                        replace status`w' = 1 if !inrange(faildate_1+ `w'*7, edate_new,remdate_new)
                        replace status`w' = 2 if inrange(faildate_1 + `w'*7, edate_new, remdate_new)
                       replace status`w' = 3 if (faildate_1 + `w'*7 >= remdate_new) & !missing(remdate_new)
                       replace status`w' = 4 if (tdate_2 <= faildate_1 + `w'*7) & !missing(tdate_2)
                       replace status`w' = 5 if (died <= faildate_1 + `w'*7) & !missing(died)
                       label define status`w' 1 "Not listed" 2 "Listed" 3 "Removed" 4 "Transported" 5 "Derived"
                       label value status`w' status`w'
                                        }
                                 }
                           }
            keep id status*
            reshape long status, i(id) j(week)
            save educ_plot_`a', replace
            }
        The error I am getting now is:
        Code:
        w not found
        I don't know how to proceed at all and how this error is coming.
        Last edited by Shalom Patole; 09 Oct 2020, 13:53.

        Comment


        • #5
          The error message tells us Stata cannot find a variable named w. That's correct, because the index w of your forvalues loop is a local macro. So
          Code:
                  if w==0{
          needs to become
          Code:
                  if `w'==0{
          as Nick showed in post #3.

          Comment


          • #6
            Thanks Will. Yes I realized that later and corrected that. So as of now I am able to generate codes for week0 which gives the status in days, but, then getting stuck as I move onto the next step. I am giving you the code as well as the traceback of the code because while I know the problem (I think) I am unable to write the code correctly to overcome it.
            Code:
            forvalues a = 0/1 {
                keep if can_college == `a'
                quietly forvalues w = 0/208 {
                       if `w' == 0 {
                           
                        forvalues d= 1/7{
             gen status`w'`d' = .
             replace status`w'`d' = 1 if !inrange(faildate_1+ `d', edate_new,remdate_new)
             replace status`w'`d' = 2 if inrange(faildate_1 + `d', edate_new, remdate_new)
             replace status`w'`d' = 3 if (faildate_1 + `d' >= remdate_new) & !missing(remdate_new)
             replace status`w'`d' = 4 if (tdate_2 <= faildate_1 + `d') & !missing(tdate_2)
             replace status`w'`d' = 5 if (died <= faildate_1 + `d') & !missing(died)
             label define status`w'`d' 1 "Not listed" 2 "Listed" 3 "Removed" 4 "Transported" 5 "Derived"
             label value status`w'`d' status`w'`d'
                        }
                    }
                else{    
             gen status`w' = .
             replace status`w' = .
             replace status`w' = 1 if !inrange(faildate_1+ `w'*7, edate_new,remdate_new)
             replace status`w' = 2 if inrange(faildate_1 + `w'*7, edate_new, remdate_new)
             replace status`w' = 3 if (faildate_1 + `w'*7 >= remdate_new) & !missing(remdate_new)
             replace status`w' = 4 if (tdate_2 <= faildate_1 + `w'*7) & !missing(tdate_2)
             replace status`w' = 5 if (died <= faildate_1 + `w'*7) & !missing(died)
             label define status`w' 1 "Not listed" 2 "Listed" 3 "Removed" 4 "Transported" 5 "Derived"
             label value status`w' status`w'
                }
                }
                }
            The error is : status01 already defined. I even tried recoding the lables for the 1st week as 6-10 but still the same issue. The set trace shows the following:
            Code:
            forvalues a = 0/1 {
            - keep if can_college == `a'
            = keep if can_college == 0
            (0 observations deleted)
            - quietly forvalues w = 0/208 {
            - if `w' == 0 {
            = if 0 == 0 {
            - forvalues d= 1/7{
            - gen status`w'`d' = .
            = gen status01 = .
            - replace status`w'`d' = 1 if !inrange(faildate_1+ `d', edate_new,remdate_new)
            = replace status01 = 1 if !inrange(faildate_1+ 1, edate_new,remdate_new)
            - replace status`w'`d' = 2 if inrange(faildate_1 + `d', edate_new, remdate_new)
            = replace status01 = 2 if inrange(faildate_1 + 1, edate_new, remdate_new)
            - replace status`w'`d' = 3 if (faildate_1 + `d' >= remdate_new) & !missing(remdate_new)
            = replace status01 = 3 if (faildate_1 + 1 >= remdate_new) & !missing(remdate_new)
            - replace status`w'`d' = 4 if (tdate_2 <= faildate_1 + `d') & !missing(tdate_2)
            = replace status01 = 4 if (tdate_2 <= faildate_1 + 1) & !missing(tdate_2)
            - replace status`w'`d' = 5 if (died <= faildate_1 + `d') & !missing(died)
            = replace status01 = 5 if (died <= faildate_1 + 1) & !missing(died)
            - label define status`w'`d' 1 "Not listed" 2 "Listed" 3 "Removed" 4 "Transported" 5 "Derived"
            = label define status01 1 "Not listed" 2 "Listed" 3 "Removed" 4 "Transported" 5 "Derived"
            ----------------------------------------------------------------------------- begin label ---
            - version 10.0
            - local vv : display "version " string(_caller()) ", missing:"
            - gettoken val : 0
            - if (strpos("`val'", "val") > 0 ) {
            = if (strpos("define", "val") > 0 ) {
              gettoken val 0 : 0
              syntax anything [, nofix]
              if "`fix'" != "" {
              local fix ", nofix"
              }
              gettoken var rest : anything
              while `"`rest'"' != "" {
              gettoken lab rest : rest
              local label "`lab'"
              }
              local vlist : list anything - lab
              if "`lab'" == "." {
              local lab ""
              }
              foreach var of varlist `vlist' {
              `vv' _label `val' `var' `lab' `fix'
              }
              }
            - else {
            - `vv' _label `macval(0)'
            = version 16, missing: _label define status01 1 "Not listed" 2 "Listed" 3 "Removed" 4 "Transported" 5 "Derived"

            Comment


            • #7
              The second time through
              Code:
              forvalues a = 0/1 {
              when `a' is 1 you will be attempting to create all the same variables you already created when `a' was 0.

              Comment


              • #8
                It seems that the error you reported in #1 arose with code you didn't report there. If so, that's not wicked but our puzzlement is not a surprise.

                Comment


                • #9
                  OK, I hear you. But now I am confused as to how STATA loops work so for values of a =0/1, I have separate 2 loops running. One is when a=0/1 and then I copy paste the whole code and change value to a=1/1. The reason is because the values for `a' are taken from a data set which is completely changed after the loop is run and the value of `'a is dropped. So I have to recreate the original data every time before running the loop allover again with different values of `a'.

                  Coming to what Will and Nick are saying I don't need to do that? That the loop will recreate values for 0 and 1 value of a without having to recreate the data set again for different values. of `'a? In that case how should I prevent this problem from occurring?

                  Comment


                  • #10
                    I cannot understand your description in post #9, and it seems to refer to code and data you have not shown us.

                    Below I start with a simplified version of the code presented in post #6 that clearly reproduces the problem you report in post #6 without all the stuff that's not part of the problem.
                    Code:
                    clear
                    input float(can_college x)
                    0 27
                    1 42
                    end
                    
                    forvalues a = 0/1 {
                        keep if can_college == `a'
                        quietly forvalues w = 0/5 {
                            if `w' == 0 {
                                 forvalues d= 1/7{
                                     gen status`w'`d' = .
                                 }
                            }
                            else {    
                                gen status`w' = .
                            }
                        }
                    }
                    Code:
                    . forvalues a = 0/1 {
                      2.     keep if can_college == `a'
                      3.     quietly forvalues w = 0/5 {
                      4.         if `w' == 0 {
                      5.              forvalues d= 1/7{
                      6.                  gen status`w'`d' = .
                      7.              }
                      8.         }
                      9.         else {    
                     10.             gen status`w' = .
                     11.         }
                     12.     }
                     13. }
                    (1 observation deleted)
                    (1 observation deleted)
                    variable status01 already defined
                    r(110);
                    There are two observations in the dataset: one with can_college==0 and one with can_college==1.

                    The first time through the forvalues a loop it drops the observation for which can_college != 0. That leaves one observation with can_college == 0. Variables status01-status07 and status1-status5 are generated.

                    The second time through the forvalues a loop it drops the observation for which can_college != 1. That leaves no remaining observations. It attempts to generate the variables status01-status07 and status1-status5 which already exist. That causes the error.

                    Comment


                    • #11
                      OK. I get the problem. Is there any way that I can overcome it? It seems to run OK when I run the code for only `d' or only `w'. But if I run both d and w in the same loop then I get this issue. Any way to circumvent this issue?

                      Comment


                      • #12
                        It seems to run OK when I run the code for only `d' or only `w'
                        The code you show in post #6 will not run OK as long as it includes the following
                        Code:
                        forvalues a = 0/1 {
                            keep if can_college == `a'
                           ...
                        }
                        Conversely, if you eliminate that outer loop it will run OK with both inner loops.
                        Code:
                        clear
                        input float(can_college x)
                        0 27
                        1 42
                        end
                        
                            quietly forvalues w = 0/5 {
                                if `w' == 0 {
                                     forvalues d= 1/7{
                                         gen status`w'`d' = .
                                     }
                                }
                                else {    
                                    gen status`w' = .
                                }
                            }
                        describe
                        Code:
                        . describe
                        
                        Contains data
                          obs:             2                          
                         vars:            14                          
                        ------------------------------------------------------------------------------------------------
                                      storage   display    value
                        variable name   type    format     label      variable label
                        ------------------------------------------------------------------------------------------------
                        can_college     float   %9.0g                 
                        x               float   %9.0g                 
                        status01        float   %9.0g                 
                        status02        float   %9.0g                 
                        status03        float   %9.0g                 
                        status04        float   %9.0g                 
                        status05        float   %9.0g                 
                        status06        float   %9.0g                 
                        status07        float   %9.0g                 
                        status1         float   %9.0g                 
                        status2         float   %9.0g                 
                        status3         float   %9.0g                 
                        status4         float   %9.0g                 
                        status5         float   %9.0g                 
                        ------------------------------------------------------------------------------------------------
                        Sorted by: 
                             Note: Dataset has changed since last saved.
                        
                        .

                        Comment


                        • #13
                          Thanks a lot Will. I understand the problem so I am now running the two loops separately and then merging them after the data frames have been created. Its painstaking but gets the work done.
                          Thanks a lot though. Your explanation of the error helped me find a solution.

                          Comment

                          Working...
                          X