%macro Lexis ( data = , /* Data set with original data, */ /* defaults to _last_ */ out = , /* Where to put the result, */ /* defaults to &data. */ entry = entry, /* Variable holding the entry date */ exit = exit, /* Variable holding the exit date */ fail = fail, /* Variable holding the exit status */ /* If any of the entry, exit or fail */ /* variables are missing the person is */ /* discarded from the computations. */ cuts = , /* Specification of the cutpoints on the */ /* the transformed scale. */ /* Syntax as for a do statement. */ /* The ONLY Mandatory argument. */ cens = 0, /* Code for censoring (may be a variable) */ scale = 1, /* Factor to transform from the scale */ /* of entry and exit to the scale */ /* where cuts and risk are given */ origin = 0, /* Origin of the transformed scale */ risk = risk, /* Variable recieving the risk time */ left = left, /* Variable recieving left endpoint of cut */ right = , /* Variable recieving right endpoint of cut */ os_left = , /* Variable recieving left endpoint of cut */ os_right = , /* Variable recieving right endpoint of cut */ /* - the latter two on original scale */ other = , /* Other dataset statements to be used in */ /* &out, e.g. %str(format var ddmmyy10.) */ disc = discrd /* Dataset holding discarded observations */ ); %if &cuts.= %then %put ERROR: cuts MUST be specified. ; %if &data.= %then %let data = &syslast. ; %if &out. = %then %do ; %let out=&data. ; %put NOTE: Output dataset not specified, input dataset %upcase(&data.) will be overwritten. ; %end ; data &disc. &out. ; set &data. ; if ( nmiss ( &entry., &exit., &fail. ) gt 0 ) then do ; output &disc. ; goto next ; end ; &other. ; drop _entry_ _exit_ _fail_ _origin_ _cut_ _cur_r _cur_l _int_r _int_l _first_ ; /* Temporary variables in this macro: _entry_ holds entry date on the transformed timescale _exit_ holds exit date on the transformed timescale _fail_ holds exit status _cut_ current cut-point _origin_ origin of the time scale _cur_l left endpoint of current risk interval _cur_r right endpoint of current risk interval _int_l left endpoint of current cut interval _int_r right endpoint of current cut interval _first_ indicator for processing of the first cut interval If variables of these names appear in the input dataset they will not be present in the output dataset. */ _origin_ = &origin. ; _entry_ = ( &entry. - _origin_ ) / &scale. ; _exit_ = ( &exit. - _origin_ ) / &scale. ; _fail_ = &fail. ; _cur_l = _entry_ ; _first_ = 1 ; do _cut_ = &cuts. ; if _first_ then do ; _cur_l = max ( _cut_, _entry_ ) ; _int_l = _cut_ ; end ; _first_ = 0 ; _int_r = _cut_ ; _cur_r = min ( _exit_, _cut_ ) ; if _cur_r gt _cur_l then do ; /* Endpoints of risk interval is put back on original scale. If any of left or right are specified the corresponding endpoint of the cut-interval are output. */ &entry. = _cur_l * &scale. + _origin_ ; &exit. = _cur_r * &scale. + _origin_ ; &risk. = _cur_r - _cur_l ; log_risk = log ( &risk. ) ; &fail. = _fail_ * ( _exit_ eq _cur_r ) + &cens. * ( _exit_ gt _cur_r ) ; %if &left.^= %then &left. = _int_l ; ; %if &right.^= %then &right. = _int_r ; ; %if &os_left.^= %then &os_left. = _int_l * &scale. + _origin_ ; ; %if &os_right.^= %then &os_right. = _int_r * &scale. + _origin_ ; ; output &out. ; end ; _cur_l = max ( _entry_, _cut_ ) ; _int_l = _cut_ ; end ; next: ; run ; %mend Lexis ;