*! version 2.0 dgc/mh 8 Sept 1995 (STB-27: ssa7) program define lexis version 3.1 local varlist "req ex min(3) max(3)" local if "opt" local in "opt" local options "BReaks(string) GENerate(string) UPdate(string)" parse "`*'" parse "`varlist'", parse(" ") local timin `1' local fail `2' local time `3' if "`generate'"=="" { di in re "needs variable name for new time bands" exit } if "`breaks'"=="" { di in re "needs breaks" exit } confirm new var `generate' tempvar id timout n ta tb tt quietly { drop if `timin'==. |`fail'==. | `time'==. gen `tt' = . * checks that breaks are present if "`breaks'"==""{ di in re "Must supply breaks for time scale" exit } * checks whether timin has been updated * during previous call to lexis cap sort _lexis if _rc==0 { by _lexis: replace `tt'=( `timin'[_n+1]-`timin'[_n] )/ `time' count if round(`tt',1) != 1 & `tt' != . if _result(1) > 0 { noi di in re " `timin' needs to be updated - go back to start" exit 198 } } else { gen int _lexis = _n } gen int `id'=_n gen `timout' = `timin' + `time' * adjusts records which fall outside the breaks parse "`breaks'", parse(",") local min = `1' while "`1'"!=""{ local max=`1' if "`3'"!="" { if `1' >= `3'{ di in re /* */"Breaks must be in ascending sequence" exit 198 } } mac shift mac shift } #delimit ; count if `timout'<=`min'; if _result(1)>0 {; noi di in ye _result(1) in bl _col(6) "records finish before first break - dropped"; drop if `timout'<=`min'; }; count if `timin'>=`max'; if _result(1)>0 {; noi di in ye _result(1) in bl _col(6) "records start after last break - dropped"; drop if `timin'>=`max'; }; count if `timout'>`max'; if _result(1)>0 {; noi di in ye _result(1) in bl _col(6) "records end after last break - right censored"; replace `fail'=cond(`timout'>`max',0,`fail'); replace `timout'= cond(`timout'>`max',`max',`timout'); }; count if `timin'<`min'; if _result(1)>0 {; noi di in ye _result(1) in bl _col(6) "records start before first break - left censored"; replace `tt'= cond(`timin'<`min',`min'-`timin',0); replace `timin' = `timin'+`tt'; if "`update'" != "" {; parse "`update'", parse(" "); while "`1'" != "" {; replace `1'=`1'+`tt'; mac shift; }; }; }; replace `time'=`timout'-`timin'; #delimit cr * calculates number of bands each subject spans gen `ta'=0 gen `tb'=0 parse "`breaks'", parse(",") while "`1'"!=""{ replace `ta'=`ta'+1 if `timin' >= `1' replace `tb'=`tb'+1 if `timout' > `1' mac shift mac shift } gen int `n'=`tb'-`ta'+1 * checks whether any record spans more than one band count if `n'> 1 if _result(1) ==0 { gen int `generate'=`ta' - 1 * sort `id' noi di in bl _col(6) "No extra records created" exit } else { replace `n' = `n' - 1 summ `n' noi di in ye _result(1)*_result(3) in bl _col(6) /* */ "extra records created" replace `n' = `n' + 1 * expands records and generates band number expand `n' sort `id' by `id': gen int `generate' = `ta' + _n - 2 } * update timin, timout, time, and fail parse "`breaks'", parse(",") local i=0 while "`3'" != "" { replace `ta'=`1' if `generate'==`i' replace `tb'=`3' if `generate'==`i' mac shift mac shift local i=`i'+1 } replace `generate' = `ta' by `id': replace `ta'=`timin' if _n==1 by `id': replace `tb'=`timout' if _n==_N by `id': replace `fail'=0 if _n!=_N replace `timin'=`ta' replace `timout'=`tb' replace `time' = `timout' - `timin' *makes list of entry variables and updates them if "`update'" != "" { parse "`update'", parse(" ") while "`1'" != "" { by `id': replace /* */ `1' = `1'[_n-1] + `time'[_n-1] if _n>1 mac shift } } noi di "" #delimit ; noi di in bl "NOTE: Following lexis expansion on" in gr " `timin'" _newline in bl "the following variables have been updated:" in gr " `timin' `update'"; #delimit cr count if `time'==0 if _result(1)>0 { noi di in ye _result(1) in bl _col(6) "records with zero /* */follow-up time dropped" } } end