*! 2.1.2 NJC 30 October 2021 *! 2.1.1 NJC 2 July 2021 *! 2.1.0 NJC 11 May 2014 *! 2.0.1 NJC 4 June 2013 *! 2.0.0 NJC 13 August 2002 * 1.8.0 spell NJC 18 October 2001 * 1.3.1 spell NJC & RG 25 June 1998 * 1.0.0 spell NJC 14 August 1997 program define tsspell, sort version 7.0 #delimit ; syntax [varname(default=none ts)] [if] [in] [, Cond(str asis) Fcond(str asis) Pcond(str asis) end(str) seq(str) spell(str) replace ] ; #delimit cr * tsset and set up for doing stuff by panel qui tsset local id "`r(panelvar)'" local time "`r(timevar)'" if "`id'" != "" { local byid "by `id':" } * observations to use marksample touse, novarlist qui count if `touse' if r(N) == 0 { error 2000 } * code modified from -tsset- * see if we have gaps local delta : char _dta[_TSdelta] if "`id'" == "" { qui count if `time' - `time'[_n-1] != `delta' & `time' < . & `touse' in 2/l } else { qui count if `time' - `time'[_n-1] != `delta' & `time' < . & `id' == `id'[_n-1] in 2/l } if r(N) > 0 { di as err "warning: data contain gaps; see help on tsspell" } * conditions defining spells local nopts = /* */ (`"`cond'"' != "") + (`"`fcond'"' != "") + (`"`pcond'"' != "") if `nopts' > 1 { di as err /* */ "must specify at most one of cond(), fcond(), pcond()" exit 198 } if `"`pcond'"' != "" { local cond `"((`pcond') > 0 & (`pcond') < .)"' } if `"`cond'"' == "" & `"`fcond'"' == "" { if "`varlist'" != "" { local fcond "(`varlist' != L.`varlist') | (_n == 1)" } else { di as err "insufficient information" exit 198 } } * generation of new variables foreach what in end seq spell { local `what' = cond("``what''" == "", "_`what'", "``what''") if "`replace'" != "" { capture confirm new variable ``what'' if _rc { drop ``what'' } } else confirm new variable ``what'' } * we're in business quietly { if `"`fcond'"' != "" { `byid' gen long `spell' = cond(`touse', sum((`fcond') & `touse'), 0) bysort `id' `spell' (`time') : /* */ gen long `seq' = _n * (`spell' > 0) } else { `byid' gen long `seq' = `cond' & `touse' `byid' replace `seq' = `seq'[_n-1] + 1 if _n > 1 & `seq' `byid' gen long `spell' = cond(`seq', sum(`touse' & `seq' == 1), 0) } `byid' gen byte `end' = /* */ cond(_n != _N, (`seq' >= `seq'[_n+1]) & `seq', `seq'[_N] > 0) compress `seq' `spell' } end