*! 2.0.0 20Aug97 (Jeroen Weesie/ICS) STB-41 ssa11 program define stsplit version 5.0 st_is capt parsoptp if _rc ~= 199 { * use parsopt to match on parentheses local cmd "`*'" * parse at() parsoptp at `cmd' local at "$S_2" /* at(str) */ local cmd "$S_3" /* cmd, with at() removed */ * parse every() parsoptp every `cmd' local every "$S_2" /* every(str) */ local cmd "$S_3" /* cmd, with every() removed */ * parse the rest local varlist "new req max(1)" local if "opt" local in "opt" local options "noSHow expr" parse "`cmd'" } else { di in bl "Install -parsoptp- if you need real expressions in at/every" * standard Stata high-level parsing local varlist "new req max(1)" local if "opt" local in "opt" local options "at(str) every(str) noSHow expr" parse "`*'" } * verify input if "`at'`every'" == "" { di in re "option { at() | every() } required" exit 100 } quietly { * scratch tempvar touse tsp v xid it0 it nt rename `varlist' `v' * sample mark `touse' `if' `in' local N0 = _N * interface to -st- characteristics st_aux, `show' local id : char _dta[st_id] local t : char _dta[st_t] local t0 : char _dta[st_t0] local d : char _dta[st_d] * regular time splittng t0,t quietly compress if "`every'" ~= "" { tempname e capt gen `e' = `every' if `touse' if _rc { di in re "syntax error in `e'" exit 198 } capt assert `e' > 0 if `touse' if _rc { di in re "every() should be a strictly positive" exit 498 } * in which intervals are t0 and t * 1 [0,e) 2 [e,2e) 3 [2e,3e) etc gen int `it0' = 1 + int(`t0' / `e') if `touse' gen int `it' = 1 + int((`t' / `e') -1E-10) if `touse' * number of intervals [t0,t) gen int `nt' = `it' - `it0' + 1 if `touse' gen int `xid' = _n if `touse' * expand expn `nt' * adapt key-variables sort `xid' by `xid' : replace `v' = `it0' + _n - 1 if `touse' by `xid' : replace `t0' = `e' * (`v'-1) if _n > 1 & `touse' by `xid' : replace `t' = `e' * `v' if _n < _N & `touse' by `xid' : replace `d' = 0 if _n < _N & `touse' } * at() splitting else { if "`expr'" == "" { * -at- should be a numlist numlist `at', real sort local at "$S_1" } else { * -at- is interpreted as a list of expressions tempvar att gen `att' = . } local nat : word count `at' replace `v' = 1 if `touse' local i 1 while `i' <= `nat' { if "`expr'" == "" { local att : word `i' of `at' } else { di in bl "add: test that expressions are increasing" local e : word `i' of `at' capt replace `att' = `e' if `touse' if _rc { di in re "syntax error in `e'" exit 198 } } * which obs to split ? gen byte `tsp' = (`att' > `t0') & (`att' < `t') & `touse' * split records local N = _N local N1 = _N+1 expand =`tsp'+1 if _N > `N' { replace `t' = `att' in 1/`N' if `tsp' replace `d' = 0 in 1/`N' if `tsp' replace `t0' = `att' in `N1'/l replace `v' = `i'+1 in `N1'/l } * adopt TVC for unsplited records replace `v' = `i'+1 if `att' <= `t0' & `touse' & ~`tsp' drop `tsp' local i = `i'+1 } } if `N0' ~= _N { noi di _n in gr "number of episodes generated : " in ye =_N-`N0' } else noi di _n in bl "no new episode generated!" rename `v' `varlist' /* end quietly */ } end program define expn capt expand = `*' if _rc { di in re "impossible to expand to splity episodes--probably too little memory" di in re "hint: drop variables if possible" exit 950 } end