Skip to Main Content

  A Program for computing “spells” | Stata Code Fragments

* make a fake data file
clear
input id month var1
1 1  0
1 2  0
1 3  1
1 4  0
1 5  0
1 6  0
1 7  1
1 8  1
1 9  1
1 10 0
1 11 1
1 12 1
1 13 0
1 14 0
1 15 0
1 16 1
1 17 1
1 18 1 
1 19 1
1 20 1
2 1  0
2 2  0
2 3  1
2 4  1
2 5  1
2 6  1
2 7  1
2 8  1
2 9  1
2 10 0
2 11 1
2 12 1
2 13 0
2 14 0
2 15 0
2 16 1
2 17 1
2 18 1 
2 19 1
2 20 1
3 1  0
3 2  0
3 3  0
3 4  0
3 5  0
3 6  0
3 7  0
3 8  0
3 9  1
3 10 1
3 11 1
3 12 1
3 13 1
3 14 1
3 15 1
3 16 1
3 17 1
3 18 1 
3 19 1
3 20 1
4 1  0
4 2  0
4 3  0
4 4  0
4 5  0
4 6  0
4 7  1
4 8  0
4 9  1
4 10 1
4 11 0
4 12 1
4 13 1
4 14 1
4 15 1
4 16 1
4 17 1
4 18 1 
4 19 1
4 20 1
end

* set line where spell must start by
local line = 6
* set minimum spell length (for it to be a spell)
local minspel = 2

* can do find and replace to change these variable names
* id variable is named "id"
* month variable is named "month"
* binary variable is called "var1"

sort id month
* make f_id which is 0/1 if first id of group
generate f_id = 0
quietly by id : replace f_id=1 if _n == 1

* make l_id which is 0/1 if last id of group
generate l_id = 0
quietly by id : replace l_id=1 if _N == _n

* initialize variables
gen sp_strt = 0 /* start of spell */
gen sp_end  = 0 /* end of spell   */
gen sp_len  = 0 /* spell length   */

* cycle through obs, 1 to _N, examining spells
local obs = 1
while (`obs' <= _N) {

  * initialize vars at start of ID
  if f_id[`obs']==1 {
    local start = 0   /* macro var with start of spell */
    local stop  = 0   /* macro var with end of spell */
    local inspel = 0  /* 0/1 if in spell */
    local hadspel = 0 /* 0/1 if already found a spell for this id */
  }

  * if 1, try to identify start of spell
  if var1[`obs'] == 1 {
    * start of spell
    if (`inspel' == 0) & (`hadspel' == 0) {
      local inspel = 1
      local start = month[`obs']
      replace sp_strt = 1 in `obs' 
    }
  }

  * if 0, try to identify end of spell
  if var1[`obs'] == 0 {
    * are we in a spell
    if (`inspel' == 1) & (`hadspel' == 0) {
      replace sp_end = -1 in `obs'

      * does the spell start after the line, 
      *  or end after the line, and is spell long enough
      if ( (`start' >= `line') | (month[`obs'-1] >= `line') ) & ///
         ((month[`obs'-1]-`start'+1) >= `minspel')  { 
            local stop = month[`obs'-1]
            replace sp_end = 1 in `obs'
            local hadspel = 1
      }
      else {
        * otherwise, reset spell info
        local inspel = 0
        local start = 0
      }
    }
  }
  
  * if at last observation for id
  if (l_id[`obs'] == 1) {
    * check to see if in a spell not completed
    if (`inspel' == 1) & (`hadspel' == 0) {
      local stop = month[`obs']
    }
    * store spell info in last observation for id
    replace sp_strt = `start' in `obs'
    replace sp_end  = `stop'  in `obs'
    replace sp_len  = `stop' - `start' + 1 in `obs'
  }

  * add 1 to obs
  local obs = `obs' + 1
}

* have a look at results to see if OK
clist month var1 sp*

* keep just last obs
quietly by id: keep if _N == _n
keep id sp*

* look at final values
clist