*! version 7.0.3 10June2001 * Written by Peter Cummings /* dblpair.ado */ /* this version uses delta method variance estimator */ program define dblpair, rclass version 7.0 syntax varlist(min=2 max=2 numeric) [if] [in], /* */ [level(real .95)] driver(string) /* */ group(varname) [oby(varlist)] [vby(varlist)] marksample touse tokenize `varlist' tempvar outcome qui gen byte `outcome' = `1' if `touse' tempvar expos qui gen byte `expos' = `2' if `touse' tempvar drivern qui gen byte `drivern'= `driver' if `touse' tempvar pass qui gen byte `pass' = `drivern'==0 if `touse' markout `touse' `pass' `oby' `vby' preserve qui keep if `touse' /* check that outcome is coded 0/1 */ capture assert `outcome'==0 | `outcome'==1 | `outcome'==. if _rc~=0 { di in re "Outcome " in ye "`1'" /* */ in re " not coded 0/1" exit 450 } /* check exposure is coded 0/1 */ capture assert `expos'==0 | `expos'==1 | `expos'==. if _rc~=0 { di in re "Exposure " in ye "`2'" /* */ in re " not coded 0/1" exit 450 } /* check that groups are never greater than 2 */ sort `group' tempvar grpct qui by `group': gen `grpct' = _N capture assert `grpct' <3 if _rc~=0 { di in re "Some groups are greater than 2" exit 459 } /* convert 2 record format to 1 record format */ sort `group' `pass' tempvar miss1 miss2 qui by `group': gen byte `miss1' = /* */ `touse'[2] == 0 | `expos'[2]==. | `outcome'[2]==. qui by `group': gen byte `miss2' = /* */ `touse'[1] == 0 | `expos'[1]==. | `outcome'[1]==. qui replace `miss1' = . if `miss1' ==1 qui replace `miss2' = . if `miss2' ==1 markout `touse' `miss1' `miss2' tempvar dout dexp qui by `group': gen byte `dout' = `outcome'[1] if `touse' qui by `group': gen byte `dexp' = `expos'[1] if `touse' tempvar pout pexp qui by `group': gen byte `pout' = `outcome'[2] if `touse' qui by `group': gen byte `pexp' = `expos'[2] if `touse' /* deal with occupant by variables. Create a temporary variable for each confounder in occupant list and create driver and passenger versions */ local oct: word count `oby' tokenize `oby' local i 1 /* generate the new occupant variables and put their names into local macro stro */ local stro = "" /* collect all the new variable names */ local strod= "" /* collect the new driver variable names */ local strop= "" /* collect the new passenger var names */ while `i' <= `oct' { tempvar dobyv`i' pobyv`i' qui by `group': gen int `dobyv`i'' = ``i''[1] if `touse' qui by `group': gen int `pobyv`i'' = ``i''[2] if `touse' local stro = "`stro' `dobyv`i'' `pobyv`i'' " local strod = "`strod' `dobyv`i''" local strop = "`strop' `pobyv`i''" local i = `i' + 1 } /* change 'touse' to include only the driver record */ tempvar dronly qui gen byte `dronly' = 1 if `pass' ==0 /* use only records that have at least one dead occupant */ tempvar onedead qui gen byte `onedead' = 1 if `pout'==1 | `dout'==1 /* use only pairs that are discordant on the exposure */ markout `touse' `dronly' `onedead' qui keep if `touse' tempvar prct qui count qui gen long `prct' = r(N) /* deal with vby, the vehicle variables */ local vct: word count `vby' /* GENERATE CRUDE ESTIMATES */ /* generate the driver belted to passenger unbelted ratio */ tempvar a0 b0 c0 e0 f0 g0 ii0 j0 k0 m0 n0 o0 tempvar aaa0 bbb0 ccc0 eee0 fff0 ggg0 iii0 jjj0 kkk0 mmm0 nnn0 ooo0 tempvar dbru0 /* driver belted to passenger unbelted */ tempvar duru0 /* driver unbelted to passenger unbelted */ tempvar dru0 /* driver to passenger unbelted */ tempvar vdru0 /* variance of ln dru */ tempvar dbrb0 /* driver belted to passenger belted */ tempvar durb0 /* driver unbelted to passenger belted */ tempvar drb0 /* driver to passenger belted */ tempvar vdrb0 /* variance of ln drb */ /* a b c d */ qui gen byte `aaa0' = `dexp'==1 & `dout'==1 & `pexp'==0 & `pout'==1 qui gen long `a0' = sum(`aaa0') qui replace `a0' = `a0'[_N] qui gen byte `bbb0' = `dexp'==1 & `dout'==0 & `pexp'==0 & `pout'==1 qui gen long `b0' = sum(`bbb0') qui replace `b0' = `b0'[_N] qui gen byte `ccc0' = `dexp'==1 & `dout'==1 & `pexp'==0 & `pout'==0 qui gen long `c0' = sum(`ccc0') qui replace `c0' = `c0'[_N] /* e f g h */ qui gen byte `eee0' = `dexp'==0 & `dout'==1 & `pexp'==0 & `pout'==1 qui gen long `e0' = sum(`eee0') qui replace `e0' = `e0'[_N] qui gen byte `fff0' = `dexp'==0 & `dout'==0 & `pexp'==0 & `pout'==1 qui gen long `f0' = sum(`fff0') qui replace `f0' = `f0'[_N] qui gen byte `ggg0' = `dexp'==0 & `dout'==1 & `pexp'==0 & `pout'==0 qui gen long `g0' = sum(`ggg0') qui replace `g0' = `g0'[_N] /* i j k l */ qui gen byte `iii0' = `dexp'==1 & `dout'==1 & `pexp'==1 & `pout'==1 qui gen long `ii0' = sum(`iii0') qui replace `ii0' = `ii0'[_N] qui gen byte `jjj0' = `dexp'==1 & `dout'==0 & `pexp'==1 & `pout'==1 qui gen long `j0' = sum(`jjj0') qui replace `j0' = `j0'[_N] qui gen byte `kkk0' = `dexp'==1 & `dout'==1 & `pexp'==1 & `pout'==0 qui gen long `k0' = sum(`kkk0') qui replace `k0' = `k0'[_N] /* m n o p */ qui gen byte `mmm0' = `dexp'==0 & `dout'==1 & `pexp'==1 & `pout'==1 qui gen long `m0' = sum(`mmm0') qui replace `m0' = `m0'[_N] qui gen byte `nnn0' = `dexp'==0 & `dout'==0 & `pexp'==1 & `pout'==1 qui gen long `n0' = sum(`nnn0') qui replace `n0' = `n0'[_N] qui gen byte `ooo0' = `dexp'==0 & `dout'==1 & `pexp'==1 & `pout'==0 qui gen long `o0' = sum(`ooo0') qui replace `o0' = `o0'[_N] qui gen double `dbru0' = (`a0'+`c0')/(`a0'+`b0') qui gen double `duru0' = (`e0'+`g0')/(`e0'+`f0') qui gen double `dru0' = `dbru0'/`duru0' qui gen double `vdru0' = /* */ [[[(`a0'*(`a0'+`b0'+`c0'))+(`b0'*`c0')]*(`f0'+`g0')] /* */ + [[(`e0'*(`e0'+`f0'+`g0'))+(`f0'*`g0')]*(`b0'+`c0')]] /* */ / [(`a0'+`c0')*(`a0'+`b0')*(`e0'+`f0')*(`e0'+`g0')] qui gen double `dbrb0' = (`ii0'+`k0')/(`ii0'+`j0') qui gen double `durb0' = (`m0'+`o0')/(`m0'+`n0') qui gen double `drb0' = `dbrb0'/`durb0' qui gen double `vdrb0' = /* */ [[[(`ii0'*(`ii0'+`j0'+`k0'))+(`j0'*`k0')]*(`n0'+`o0')] /* */ + [[(`m0'*(`m0'+`n0'+`o0'))+(`n0'*`o0')]*(`j0'+`k0')]] /* */ / [(`ii0'+`k0')*(`ii0'+`j0')*(`m0'+`n0')*(`m0'+`o0')] /* temporary variables for passenger to driver estimates */ tempvar pbru0 /* passenger belted to driver unbelted */ tempvar puru0 /* passenger unbelted to driver unbelted */ tempvar pru0 /* passenger to driver unbelted */ tempvar vpru0 /* variance of ln pru */ tempvar pbrb0 /* passenger belted to driver belted */ tempvar purb0 /* passenger unbelted to driver belted */ tempvar prb0 /* passenger to driver belted */ tempvar vprb0 /* variance of ln prb */ /* generate passenger to driver relative risk estimates */ qui gen double `pbru0' = (`m0'+`n0')/(`m0'+`o0') qui gen double `puru0' = (`e0'+`f0')/(`e0'+`g0') qui gen double `pru0' = `pbru0'/`puru0' qui gen double `vpru0' = /* */ [[[(`m0'*(`m0'+`o0'+`n0'))+(`o0'*`n0')]*(`f0'+`g0')] /* */ + [[(`e0'*(`e0'+`f0'+`g0'))+(`f0'*`g0')]*(`o0'+`n0')]] /* */ / [(`m0'+`n0')*(`m0'+`o0')*(`e0'+`f0')*(`e0'+`g0')] qui gen double `pbrb0' = (`ii0'+`j0')/(`ii0'+`k0') qui gen double `purb0' = (`a0'+`b0')/(`a0'+`c0') qui gen double `prb0' = `pbrb0'/`purb0' qui gen double `vprb0' = /* */ [[[(`ii0'*(`ii0'+`j0'+`k0'))+(`j0'*`k0')]*(`c0'+`b0')] /* */ + [[(`a0'*(`a0'+`c0'+`b0'))+(`c0'*`b0')]*(`j0'+`k0')]] /* */ / [(`ii0'+`k0')*(`ii0'+`j0')*(`a0'+`c0')*(`a0'+`b0')] tempvar drr0 /* driver rr */ tempvar vdrr0 /* variance of ln drr */ tempvar drru0 /* upper CI for drr */ tempvar drrl0 /* lower CI for drr */ tempvar prr0 /* passenger rr */ tempvar vprr0 /* variance of ln prr */ tempvar prru0 /* upper CI for prr */ tempvar prrl0 /* lower CI for prr */ tempvar rr0 /* rr */ qui gen double `drr0' = exp([ln(`dru0')*(1/`vdru0') /* */ + ln(`drb0')*(1/`vdrb0')] /* */ /[(1/`vdru0')+(1/`vdrb0')]) qui replace `drr0' = `dru0' if `drb0'==. qui replace `drr0' = `drb0' if `dru0'==. qui gen double `vdrr0' = 1/[(1/`vdru0')+(1/`vdrb0')] qui replace `vdrr0' = `vdru0' if `vdrb0'==. qui replace `vdrr0' = `vdrb0' if `vdru0'==. qui gen double `drru0' = exp(ln(`drr0') /* */ + invnorm(`level'*.5 + 0.5)*sqrt(`vdrr0')) qui gen double `drrl0' = exp(ln(`drr0') /* */ - invnorm(`level'*.5 + 0.5)*sqrt(`vdrr0')) qui gen double `prr0' = exp([ln(`pru0')*(1/`vpru0') /* */ + ln(`prb0')*(1/`vprb0')] /* */ /[(1/`vpru0')+(1/`vprb0')]) qui replace `prr0' = `pru0' if `prb0'==. qui replace `prr0' = `prb0' if `pru0'==. qui gen double `vprr0' = 1/[(1/`vpru0')+(1/`vprb0')] qui replace `vprr0' = `vpru0' if `vprb0'==. qui replace `vprr0' = `vprb0' if `vpru0'==. qui gen double `prru0' = exp(ln(`prr0') /* */ + invnorm(`level'*.5 + 0.5)*sqrt(`vprr0')) qui gen double `prrl0' = exp(ln(`prr0') /* */ - invnorm(`level'*.5 + 0.5)*sqrt(`vprr0')) qui gen double `rr0' = exp([ln(`drr0')*(1/`vdrr0') /* */ + ln(`prr0')*(1/`vprr0')] /* */ /[(1/`vdrr0')+(1/`vprr0')]) return scalar drr = `drr0' return scalar vdrr = `vdrr0' return scalar drru = `drru0' return scalar drrl = `drrl0' return scalar prr = `prr0' return scalar vprr = `vprr0' return scalar prru = `prru0' return scalar prrl = `prrl0' return scalar rr = `rr0' return scalar prct = `prct' /* generate results by strata according to the oby and vby variables */ /* start a big if/else loop here. Within the first part calculate and display the stratum specific estimates. The last part will just display crude estimates. */ if "`stro'`vby'" ~="" { /* large if/else starts here */ tempvar strata qui egen int `strata' = group(`stro' `vby') qui summarize `strata' tempvar strmax qui gen `strmax' = r(max) /* generate counts by stratum */ /* generate the driver belted to passenger unbelted ratio */ tempvar last tempvar a b c e f g ii j k m n o tempvar aaa bbb ccc eee fff ggg iii jjj kkk mmm nnn ooo tempvar dbru /* driver belted to passenger unbelted */ tempvar duru /* driver unbelted to passenger unbelted */ tempvar dru /* driver to passenger unbelted */ tempvar vdru /* variance of ln dru */ tempvar dbrb /* driver belted to passenger belted */ tempvar durb /* driver unbelted to passenger belted */ tempvar drb /* driver to passenger belted */ tempvar vdrb /* variance of ln drb */ /* a b c d */ sort `strata' tempvar last qui gen byte `last'=0 qui by `strata': replace `last'=1 if _n== _N qui by `strata': gen byte `aaa' = /* */ `dexp'==1 & `dout'==1 & `pexp'==0 & `pout'==1 qui by `strata': gen long `a' = sum(`aaa') qui by `strata': replace `a' = `a'[_N] qui by `strata': gen byte `bbb' = /* */ `dexp'==1 & `dout'==0 & `pexp'==0 & `pout'==1 qui by `strata': gen long `b' = sum(`bbb') qui by `strata': replace `b' = `b'[_N] qui by `strata': gen byte `ccc' = /* */ `dexp'==1 & `dout'==1 & `pexp'==0 & `pout'==0 qui by `strata': gen long `c' = sum(`ccc') qui by `strata': replace `c' = `c'[_N] /* e f g h */ qui by `strata': gen byte `eee' = /* */ `dexp'==0 & `dout'==1 & `pexp'==0 & `pout'==1 qui by `strata': gen long `e' = sum(`eee') qui by `strata': replace `e' = `e'[_N] qui by `strata': gen byte `fff' = /* */ `dexp'==0 & `dout'==0 & `pexp'==0 & `pout'==1 qui by `strata': gen long `f' = sum(`fff') qui by `strata': replace `f' = `f'[_N] qui by `strata': gen byte `ggg' = /* */ `dexp'==0 & `dout'==1 & `pexp'==0 & `pout'==0 qui by `strata': gen long `g' = sum(`ggg') qui by `strata': replace `g' = `g'[_N] /* i j k l */ qui by `strata': gen byte `iii' = /* */ `dexp'==1 & `dout'==1 & `pexp'==1 & `pout'==1 qui by `strata': gen long `ii' = sum(`iii') qui by `strata': replace `ii' = `ii'[_N] qui by `strata': gen byte `jjj' = /* */ `dexp'==1 & `dout'==0 & `pexp'==1 & `pout'==1 qui by `strata': gen long `j' = sum(`jjj') qui by `strata': replace `j' = `j'[_N] qui by `strata': gen byte `kkk' = /* */ `dexp'==1 & `dout'==1 & `pexp'==1 & `pout'==0 qui by `strata': gen long `k' = sum(`kkk') qui by `strata': replace `k' = `k'[_N] /* m n o p */ qui by `strata': gen byte `mmm' = /* */ `dexp'==0 & `dout'==1 & `pexp'==1 & `pout'==1 qui by `strata': gen long `m' = sum(`mmm') qui by `strata': replace `m' = `m'[_N] qui by `strata': gen byte `nnn' = /* */ `dexp'==0 & `dout'==0 & `pexp'==1 & `pout'==1 qui by `strata': gen long `n' = sum(`nnn') qui by `strata': replace `n' = `n'[_N] qui by `strata': gen byte `ooo' = /* */ `dexp'==0 & `dout'==1 & `pexp'==1 & `pout'==0 qui by `strata': gen long `o' = sum(`ooo') qui by `strata': replace `o' = `o'[_N] local i 1 while `i'<=`strmax' { qui count if `strata' ==`i' tempvar prct`i' qui gen long prct`i' = r(N) return scalar prct`i' = r(N) local i = `i' +1 } qui keep if `last'==1 qui gen double `dbru' = (`a'+`c')/(`a'+`b') qui gen double `duru' = (`e'+`g')/(`e'+`f') qui gen double `dru' = `dbru'/`duru' qui gen double `vdru' = /* */ [[[(`a'*(`a'+`b'+`c'))+(`b'*`c')]*(`f'+`g')] /* */ + [[(`e'*(`e'+`f'+`g'))+(`f'*`g')]*(`b'+`c')]] /* */ / [(`a'+`c')*(`a'+`b')*(`e'+`f')*(`e'+`g')] qui gen double `dbrb' = (`ii'+`k')/(`ii'+`j') qui gen double `durb' = (`m'+`o')/(`m'+`n') qui gen double `drb' = `dbrb'/`durb' qui gen double `vdrb' = /* */ [[[(`ii'*(`ii'+`j'+`k'))+(`j'*`k')]*(`n'+`o')] /* */ + [[(`m'*(`m'+`n'+`o'))+(`n'*`o')]*(`j'+`k')]] /* */ / [(`ii'+`k')*(`ii'+`j')*(`m'+`n')*(`m'+`o')] /* temporary variables for passenger to driver estimates */ tempvar pbru /* passenger belted to driver unbelted */ tempvar puru /* passenger unbelted to driver unbelted */ tempvar pru /* passenger to driver unbelted */ tempvar vpru /* variance of ln pru */ tempvar pbrb /* passenger belted to driver belted */ tempvar purb /* passenger unbelted to driver belted */ tempvar prb /* passenger to driver belted */ tempvar vprb /* variance of ln prb */ /* generate passenger to driver relative risk estimates */ qui gen double `pbru' = (`m'+`n')/(`m'+`o') qui gen double `puru' = (`e'+`f')/(`e'+`g') qui gen double `pru' = `pbru'/`puru' qui gen double `vpru' = /* */ [[[(`m'*(`m'+`o'+`n'))+(`o'*`n')]*(`f'+`g')] /* */ + [[(`e'*(`e'+`f'+`g'))+(`f'*`g')]*(`o'+`n')]] /* */ / [(`m'+`n')*(`m'+`o')*(`e'+`f')*(`e'+`g')] qui gen double `pbrb' = (`ii'+`j')/(`ii'+`k') qui gen double `purb' = (`a'+`b')/(`a'+`c') qui gen double `prb' = `pbrb'/`purb' qui gen double `vprb' = /* */ [[[(`ii'*(`ii'+`j'+`k'))+(`j'*`k')]*(`c'+`b')] /* */ + [[(`a'*(`a'+`c'+`b'))+(`c'*`b')]*(`j'+`k')]] /* */ / [(`ii'+`k')*(`ii'+`j')*(`a'+`c')*(`a'+`b')] tempvar drr /* driver rr */ tempvar vdrr /* variance of ln drr */ tempvar drru /* upper CI for drr */ tempvar drrl /* lower CI for drr */ tempvar prr /* passenger rr */ tempvar vprr /* variance of ln prr */ tempvar prru /* upper CI for prr */ tempvar prrl /* lower CI for prr */ tempvar rr /* rr */ qui gen double `drr' = exp([ln(`dru')*(1/`vdru') /* */ + ln(`drb')*(1/`vdrb')] /* */ /[(1/`vdru')+(1/`vdrb')]) qui replace `drr' = `dru' if `drb'==. qui replace `drr' = `drb' if `dru'==. qui gen double `vdrr' = 1/[(1/`vdru')+(1/`vdrb')] qui replace `vdrr' = `vdru' if `vdrb'==. qui replace `vdrr' = `vdrb' if `vdru'==. qui gen double `drru' = exp(ln(`drr') /* */ + invnorm(`level'*.5 + 0.5)*sqrt(`vdrr')) qui gen double `drrl' = exp(ln(`drr') /* */ - invnorm(`level'*.5 + 0.5)*sqrt(`vdrr')) qui gen double `prr' = exp([ln(`pru')*(1/`vpru') /* */ + ln(`prb')*(1/`vprb')] /* */ /[(1/`vpru')+(1/`vprb')]) qui replace `prr' = `pru' if `prb'==. qui replace `prr' = `prb' if `pru'==. qui gen double `vprr' = 1/[(1/`vpru')+(1/`vprb')] qui replace `vprr' = `vpru' if `vprb'==. qui replace `vprr' = `vprb' if `vpru'==. qui gen double `prru' = exp(ln(`prr') /* */ + invnorm(`level'*.5 + 0.5)*sqrt(`vprr')) qui gen double `prrl' = exp(ln(`prr') /* */ - invnorm(`level'*.5 + 0.5)*sqrt(`vprr')) qui gen double `rr' = exp([ln(`drr')*(1/`vdrr') /* */ + ln(`prr')*(1/`vprr')] /* */ /[(1/`vdrr')+(1/`vprr')]) /* now combine results across strata using variance weighted summaries. Use "a" for "adjusted". */ tempvar ladrrt /* top part of ln drr calculation */ qui gen double `ladrrt' = sum((1/`vdrr') * ln(`drr')) qui replace `ladrrt' = `ladrrt'[_N] tempvar ladrrb /* bottom part of ln drr calc */ qui gen double `ladrrb' = sum(1/`vdrr') qui replace `ladrrb' = `ladrrb'[_N] tempvar adrr qui gen double `adrr' = exp(`ladrrt'/`ladrrb') /* now combine variance of this estimate, which is just the inverse of the sum of the weights */ tempvar vadrr /* variance of ln adrr */ qui gen double `vadrr' = (1/`ladrrb') tempvar adrru qui gen double `adrru' = exp(ln(`adrr') /* */ + invnorm(`level'*.5 + 0.5)*sqrt(`vadrr')) tempvar adrrl qui gen double `adrrl' = exp(ln(`adrr') /* */ - invnorm(`level'*.5 + 0.5)*sqrt(`vadrr')) tempvar laprrt /* top part of ln aprr calculation */ qui gen double `laprrt' = sum((1/`vprr') * ln(`prr')) qui replace `laprrt' = `laprrt'[_N] tempvar laprrb /* bottom part of ln aprr calc */ qui gen double `laprrb' = sum(1/`vprr') qui replace `laprrb' = `laprrb'[_N] tempvar aprr qui gen double `aprr' = exp(`laprrt'/`laprrb') /* now combine variance of this estimate, which is just the inverse of the sum of the weights */ tempvar vaprr /* variance of ln aprr */ qui gen double `vaprr' = (1/`laprrb') tempvar aprru qui gen double `aprru' = exp(ln(`aprr') /* */ + invnorm(`level'*.5 + 0.5)*sqrt(`vaprr')) tempvar aprrl qui gen double `aprrl' = exp(ln(`aprr') /* */ - invnorm(`level'*.5 + 0.5)*sqrt(`vaprr')) tempvar arr qui gen double `arr' = exp([ln(`adrr')*(1/`vadrr') /* */ + ln(`aprr')*(1/`vaprr')]/[(1/`vadrr')+(1/`vaprr')]) /* tests of homogeneity */ tempvar dchi pchi ddf pdf dpchi ppchi qui gen double `dchi' = sum(((ln(`drr')-ln(`adrr'))^2)/`vdrr') qui replace `dchi' = `dchi'[_N] qui gen double `pchi' = sum(((ln(`prr')-ln(`aprr'))^2)/`vprr') qui replace `pchi' = `pchi'[_N] qui count if `drr'~=. qui gen int `ddf' = r(N) -1 qui count if `prr'~=. qui gen int `pdf' = r(N) -1 qui gen double `dpchi' = chi2tail(`ddf',`dchi') qui gen double `ppchi' = chi2tail(`pdf',`pchi') sort `strata' local i 1 while `i'<=`strmax' { return scalar drr`i' = `drr'[`i'] return scalar vdrr`i' = `vdrr'[`i'] return scalar drru`i' = `drru'[`i'] return scalar drrl`i' = `drrl'[`i'] return scalar prr`i' = `prr'[`i'] return scalar vprr`i' = `vprr'[`i'] return scalar prru`i' = `prru'[`i'] return scalar prrl`i' = `prrl'[`i'] return scalar rr`i' = `rr'[`i'] local i = `i' +1 } return scalar adrr = `adrr'[_N] return scalar avdrr = `vadrr'[_N] return scalar adrru = `adrru'[_N] return scalar adrrl = `adrrl'[_N] return scalar aprr = `aprr'[_N] return scalar avprr = `vaprr'[_N] return scalar aprru = `aprru'[_N] return scalar aprrl = `aprrl'[_N] return scalar arr = `arr'[_N] /* at this point, compute a new crude rr which uses data only from strata which have either a prr variance or a drr variance */ tempvar a0n b0n c0n e0n f0n g0n ii0n j0n k0n m0n n0n o0n tempvar dbru0n duru0n dru0n dbrb0n durb0n drb0n tempvar vdru0n vdrb0n gsort -`vdrr', mfirst qui gen long `a0n' = sum(`a') if `vdrr'~=. qui replace `a0n' = `a0n'[_N] qui gen long `b0n' = sum(`b') if `vdrr'~=. qui replace `b0n' = `b0n'[_N] qui gen long `c0n' = sum(`c') if `vdrr'~=. qui replace `c0n' = `c0n'[_N] qui gen long `e0n' = sum(`e') if `vdrr'~=. qui replace `e0n' = `e0n'[_N] qui gen long `f0n' = sum(`f') if `vdrr'~=. qui replace `f0n' = `f0n'[_N] qui gen long `g0n' = sum(`g') if `vdrr'~=. qui replace `g0n' = `g0n'[_N] qui gen long `ii0n' = sum(`ii') if `vdrr'~=. qui replace `ii0n' = `ii0n'[_N] qui gen long `j0n' = sum(`j') if `vdrr'~=. qui replace `j0n' = `j0n'[_N] qui gen long `k0n' = sum(`k') if `vdrr'~=. qui replace `k0n' = `k0n'[_N] qui gen long `m0n' = sum(`m') if `vdrr'~=. qui replace `m0n' = `m0n'[_N] qui gen long `n0n' = sum(`n') if `vdrr'~=. qui replace `n0n' = `n0n'[_N] qui gen long `o0n' = sum(`o') if `vdrr'~=. qui replace `o0n' = `o0n'[_N] qui gen double `dbru0n' = (`a0n'+`c0n')/(`a0n'+`b0n') qui gen double `duru0n' = (`e0n'+`g0n')/(`e0n'+`f0n') qui gen double `dru0n' = `dbru0n'/`duru0n' qui gen double `vdru0n' = /* */ [[[(`a0n'*(`a0n'+`b0n'+`c0n'))+(`b0n'*`c0n')]*(`f0n'+`g0n')] /* */ + [[(`e0n'*(`e0n'+`f0n'+`g0n'))+(`f0n'*`g0n')]*(`b0n'+`c0n')]] /* */ / [(`a0n'+`c0n')*(`a0n'+`b0n')*(`e0n'+`f0n')*(`e0n'+`g0n')] qui gen double `dbrb0n' = (`ii0n'+`k0n')/(`ii0n'+`j0n') qui gen double `durb0n' = (`m0n'+`o0n')/(`m0n'+`n0n') qui gen double `drb0n' = `dbrb0n'/`durb0n' qui gen double `vdrb0n' = /* */ [[[(`ii0n'*(`ii0n'+`j0n'+`k0n'))+(`j0n'*`k0n')]*(`n0n'+`o0n')] /* */ + [[(`m0n'*(`m0n'+`n0n'+`o0n'))+(`n0n'*`o0n')]*(`j0n'+`k0n')]] /* */ / [(`ii0n'+`k0n')*(`ii0n'+`j0n')*(`m0n'+`n0n')*(`m0n'+`o0n')] /* temporary variables for passenger to driver estimates. These variables are for a new crude estimate that uses stratified data only. */ tempvar pbru0n /* passenger belted to driver unbelted */ tempvar puru0n /* passenger unbelted to driver unbelted */ tempvar pru0n /* passenger to driver unbelted */ tempvar vpru0n /* variance of ln pru */ tempvar pbrb0n /* passenger belted to driver belted */ tempvar purb0n /* passenger unbelted to driver belted */ tempvar prb0n /* passenger to driver belted */ tempvar vprb0n /* variance of ln prb */ /* I will redo a0n through o0n now for passengers */ gsort -`vprr', mfirst qui replace `a0n' = sum(`a') if `vprr'~=. qui replace `a0n' = `a0n'[_N] qui replace `b0n' = sum(`b') if `vprr'~=. qui replace `b0n' = `b0n'[_N] qui replace `c0n' = sum(`c') if `vprr'~=. qui replace `c0n' = `c0n'[_N] qui replace `e0n' = sum(`e') if `vprr'~=. qui replace `e0n' = `e0n'[_N] qui replace `f0n' = sum(`f') if `vprr'~=. qui replace `f0n' = `f0n'[_N] qui replace `g0n' = sum(`g') if `vprr'~=. qui replace `g0n' = `g0n'[_N] qui replace `ii0n' = sum(`ii') if `vprr'~=. qui replace `ii0n' = `ii0n'[_N] qui replace `j0n' = sum(`j') if `vprr'~=. qui replace `j0n' = `j0n'[_N] qui replace `k0n' = sum(`k') if `vprr'~=. qui replace `k0n' = `k0n'[_N] qui replace `m0n' = sum(`m') if `vprr'~=. qui replace `m0n' = `m0n'[_N] qui replace `n0n' = sum(`n') if `vprr'~=. qui replace `n0n' = `n0n'[_N] qui replace `o0n' = sum(`o') if `vprr'~=. qui replace `o0n' = `o0n'[_N] /* generate passenger to driver relative risk estimates. These are for a crude estimate that uses the stratified data. */ qui gen double `pbru0n' = (`m0n'+`n0n')/(`m0n'+`o0n') qui gen double `puru0n' = (`e0n'+`f0n')/(`e0n'+`g0n') qui gen double `pru0n' = `pbru0n'/`puru0n' qui gen double `vpru0n' = /* */ [[[(`m0n'*(`m0n'+`o0n'+`n0n'))+(`o0n'*`n0n')]*(`f0n'+`g0n')] /* */ + [[(`e0n'*(`e0n'+`f0n'+`g0n'))+(`f0n'*`g0n')]*(`o0n'+`n0n')]] /* */ / [(`m0n'+`n0n')*(`m0n'+`o0n')*(`e0n'+`f0n')*(`e0n'+`g0n')] qui gen double `pbrb0n' = (`ii0n'+`j0n')/(`ii0n'+`k0n') qui gen double `purb0n' = (`a0n'+`b0n')/(`a0n'+`c0n') qui gen double `prb0n' = `pbrb0n'/`purb0n' qui gen double `vprb0n' = /* */ [[[(`ii0n'*(`ii0n'+`j0n'+`k0n'))+(`j0n'*`k0n')]*(`c0n'+`b0n')] /* */ + [[(`a0n'*(`a0n'+`c0n'+`b0n'))+(`c0n'*`b0n')]*(`j0n'+`k0n')]] /* */ / [(`ii0n'+`k0n')*(`ii0n'+`j0n')*(`a0n'+`c0n')*(`a0n'+`b0n')] tempvar drr0n /* driver rr */ tempvar vdrr0n /* variance of ln drr */ tempvar drru0n /* upper CI for drr */ tempvar drrl0n /* lower CI for drr */ tempvar prr0n /* passenger rr */ tempvar vprr0n /* variance of ln prr */ tempvar prru0n /* upper CI for prr */ tempvar prrl0n /* lower CI for prr */ tempvar rr0n /* rr */ qui gen double `drr0n' = exp([ln(`dru0n')*(1/`vdru0n') /* */ + ln(`drb0n')*(1/`vdrb0n')] /* */ /[(1/`vdru0n')+(1/`vdrb0n')]) qui replace `drr0n' = `dru0n' if `drb0n'==. qui replace `drr0n' = `drb0n' if `dru0n'==. qui gen double `vdrr0n' = 1/[(1/`vdru0n')+(1/`vdrb0n')] qui replace `vdrr0n' = `vdru0n' if `vdrb0n'==. qui replace `vdrr0n' = `vdrb0n' if `vdru0n'==. qui gen double `drru0n' = exp(ln(`drr0n') /* */ + invnorm(`level'*.5 + 0.5)*sqrt(`vdrr0n')) qui gen double `drrl0n' = exp(ln(`drr0n') /* */ - invnorm(`level'*.5 + 0.5)*sqrt(`vdrr0n')) qui gen double `prr0n' = exp([ln(`pru0n')*(1/`vpru0n') /* */ + ln(`prb0n')*(1/`vprb0n')] /* */ /[(1/`vpru0n')+(1/`vprb0n')]) qui replace `prr0n' = `pru0n' if `prb0n'==. qui replace `prr0n' = `prb0n' if `pru0n'==. qui gen double `vprr0n' = 1/[(1/`vpru0n')+(1/`vprb0n')] qui replace `vprr0n' = `vpru0n' if `vprb0n'==. qui replace `vprr0n' = `vprb0n' if `vpru0n'==. qui gen double `prru0n' = exp(ln(`prr0n') /* */ + invnorm(`level'*.5 + 0.5)*sqrt(`vprr0n')) qui gen double `prrl0n' = exp(ln(`prr0n') /* */ - invnorm(`level'*.5 + 0.5)*sqrt(`vprr0n')) qui gen double `rr0n' = exp([ln(`drr0n')*(1/`vdrr0n') /* */ + ln(`prr0n')*(1/`vprr0n')] /* */ /[(1/`vdrr0n')+(1/`vprr0n')]) return scalar drr0n = `drr0n' return scalar vdrr0n = `vdrr0n' return scalar drru0n = `drru0n' return scalar drrl0n = `drrl0n' return scalar prr0n = `prr0n' return scalar vprr0n = `vprr0n' return scalar prru0n = `prru0n' return scalar prrl0n = `prrl0n' return scalar rr0n = `rr0n' /* this ends the section of new crude estimates */ /* create macros for value labels for strata display */ local names `oby' `oby' `vby' tokenize `names' capture local lbl1 : value label `1' capture local lbl2 : value label `2' capture local lbl3 : value label `3' capture local lbl4 : value label `4' capture local lbl5 : value label `5' capture local lbl6 : value label `6' /* confine output length to 72 characters */ di local c1 = 73 - (8 + length("Pairs used = ")) di as text "Double-pair method" _col(`c1') /* */ "Pairs used = " as result %8.0g `prct' di as text "Stratified by: `oby' `vby' di as text "{hline 8}{c TT}{hline 63}" if `oct' ~= 0 & `vct' ~= 0 { local colp = 11 + 9*`oct' /* passenger column */ local colv = 11 + 2*9*`oct' /* vehicle column */ di as text _col(9)"{c |}" _col(11)"Driver" /* */ _col(`colp')"Pass" _col(`colv')"Vehicle" } else if `oct'==0 & `vct' ~= 0 { di as text _col(9)"{c |}" _col(11)"Vehicle" } else { local colp = 11 + 9*`oct' /* passenger column */ di as text _col(9)"{c |}" _col(11)"Driver" /* */ _col(`colp')"Pass" } /* variable list will be 2*oct + 1*vct */ tokenize `oby' `oby' `vby' di as text "stratum {c |}" _col(11)"`1'" _col(20)"`2'" /* */ _col(29)"`3'" _col(38)"`4'" /* */ _col(47)"`5'" _col(56)"`6'" _col(65)"count" di as text "{hline 8}{c +}{hline 63}" local totct: word count `oby' `oby' `vby' tokenize `strod' `strop' `vby' sort `strata' if `totct' == 6 { label values `1' `lbl1' /* label values */ label values `2' `lbl2' label values `3' `lbl3' label values `4' `lbl4' label values `5' `lbl5' label values `6' `lbl6' local i 1 while `i' <=`strmax' { if "`lbl1'" ~= "" { local disp1 = `1'[`i'] local dsplbl1 : label `labl1' `disp1' } else { capture local dsplbl1 = `1'[`i'] } if "`lbl2'" ~= "" { local disp2 = `2'[`i'] local dsplbl2 : label `labl2' `disp2' } else { capture local dsplbl2 = `2'[`i'] } if "`lbl3'" ~= "" { local disp3 = `3'[`i'] local dsplbl3 : label `labl3' `disp3' } else { capture local dsplbl3 = `3'[`i'] } if "`lbl4'" ~= "" { local disp4 = `4'[`i'] local dsplbl4 : label `labl4' `disp4' } else { capture local dsplbl4 = `4'[`i'] } if "`lbl5'" ~= "" { local disp5 = `5'[`i'] local dsplbl5 : label `labl5' `disp5' } else { capture local dsplbl5 = `5'[`i'] } if "`lbl6'" ~= "" { local disp6 = `6'[`i'] local dsplbl6 : label `labl6' `disp6' } else { capture local dsplbl6 = `6'[`i'] } di as result `stratum'[`i'] as text _col(9)"{c |}" */ as result /* */ _col(11)"`dsplbl1'" /* */ _col(20)"`dsplbl2'" /* */ _col(29)"`dsplbl3'" /* */ _col(38)"`dsplbl4'" /* */ _col(47)"`dsplbl5'" /* */ _col(56)"`dsplbl6'" /* */ _col(65) prct`i'[`i'] local i = `i'+1 } } else if `totct' == 5 { label values `1' `lbl1' /* label values */ label values `2' `lbl2' label values `3' `lbl3' label values `4' `lbl4' label values `5' `lbl5' local i 1 while `i' <=`strmax' { if "`lbl1'" ~= "" { local disp1 = `1'[`i'] local dsplbl1 : label `lbl1' `disp1' } else { capture local dsplbl1 = `1'[`i'] } if "`lbl2'" ~= "" { local disp2 = `2'[`i'] local dsplbl2 : label `lbl2' `disp2' } else { capture local dsplbl2 = `2'[`i'] } if "`lbl3'" ~= "" { local disp3 = `3'[`i'] local dsplbl3 : label `lbl3' `disp3' } else { capture local dsplbl3 = `3'[`i'] } if "`lbl4'" ~= "" { local disp4 = `4'[`i'] local dsplbl4 : label `lbl4' `disp4' } else { capture local dsplbl4 = `4'[`i'] } if "`lbl5'" ~= "" { local disp5 = `5'[`i'] local dsplbl5 : label `lbl5' `disp5' } else { capture local dsplbl5 = `5'[`i'] } di as result `stratum'[`i'] as text _col(9)"{c |}" /* */ as result /* */ _col(11)"`dsplbl1'" /* */ _col(20)"`dsplbl2'" /* */ _col(29)"`dsplbl3'" /* */ _col(38)"`dsplbl4'" /* */ _col(47)"`dsplbl5'" /* */ _col(65) prct`i'[`i'] local i = `i'+1 } } else if `totct' == 4 { label values `1' `lbl1' /* label values */ label values `2' `lbl2' label values `3' `lbl3' label values `4' `lbl4' local i 1 while `i' <=`strmax' { if "`lbl1'" ~= "" { local disp1 = `1'[`i'] local dsplbl1 : label `lbl1' `disp1' } else { capture local dsplbl1 = `1'[`i'] } if "`lbl2'" ~= "" { local disp2 = `2'[`i'] local dsplbl2 : label `lbl2' `disp2' } else { capture local dsplbl2 = `2'[`i'] } if "`lbl3'" ~= "" { local disp3 = `3'[`i'] local dsplbl3 : label `lbl3' `disp3' } else { capture local dsplbl3 = `3'[`i'] } if "`lbl4'" ~= "" { local disp4 = `4'[`i'] local dsplbl4 : label `lbl4' `disp4' } else { capture local dsplbl4 = `4'[`i'] } di as result `stratum'[`i'] as text _col(9)"{c |}" /* */ as result /* */ _col(11)"`dsplbl1'" /* */ _col(20)"`dsplbl2'" /* */ _col(29)"`dsplbl3'" /* */ _col(38)"`dsplbl4'" /* */ _col(65) prct`i'[`i'] local i = `i'+1 } } else if `totct' == 3 { label values `1' `lbl1' /* label values */ label values `2' `lbl2' label values `3' `lbl3' local i 1 while `i' <=`strmax' { if "`lbl1'" ~= "" { local disp1 = `1'[`i'] local dsplbl1 : label `lbl1' `disp1' } else { capture local dsplbl1 = `1'[`i'] } if "`lbl2'" ~= "" { local disp2 = `2'[`i'] local dsplbl2 : label `lbl2' `disp2' } else { capture local dsplbl2 = `2'[`i'] } if "`lbl3'" ~= "" { local disp3 = `3'[`i'] local dsplbl3 : label `lbl3' `disp3' } else { capture local dsplbl3 = `3'[`i'] } di as result `stratum'[`i'] as text _col(9)"{c |}" as result /* */ _col(11)"`dsplbl1'" /* */ _col(20)"`dsplbl2'" /* */ _col(29)"`dsplbl3'" /* */ _col(65) prct`i'[`i'] local i = `i'+1 } } else if `totct' == 2 { label values `1' `lbl1' /* label values */ label values `2' `lbl2' local i 1 while `i' <=`strmax' { if "`lbl1'" ~= "" { local disp1 = `1'[`i'] local dsplbl1 : label `lbl1' `disp1' } else { capture local dsplbl1 = `1'[`i'] } if "`lbl2'" ~= "" { local disp2 = `2'[`i'] local dsplbl2 : label `lbl2' `disp2' } else { capture local dsplbl2 = `2'[`i'] } di as result `stratum'[`i'] as text _col(9)"{c |}" as result /* */ _col(11)"`dsplbl1'" /* */ _col(20)"`dsplbl2'" /* */ _col(65) prct`i'[`i'] local i = `i'+1 } } else { label values `1' `lbl1' /* label values */ local i 1 while `i' <=`strmax' { if "`lbl1'" ~= "" { local disp1 = `1'[`i'] local dsplbl1 : label `lbl1' `disp1' } else { capture local dsplbl1 = `1'[`i'] } di as result `stratum'[`i'] as text _col(9)"{c |}" as result /* */ _col(11)"`dsplbl1'" /* */ _col(65) prct`i'[`i'] local i = `i'+1 } } di as text "{hline 8}{c BT}{hline 63}" di local levpc = `level'*100 di as text "Relative Risk estimates" /* */ _col(39)"Confidence interval level = " /* */ %4.1f as result `levpc' " %" di as text "{hline 8}{c TT}{hline 63}" di as text "stratum {c |}" _col(11)"dRR" _col(19)"[Conf. Interval]" /* */ _col(37)"pRR" _col(45)"[Conf. Interval]" /* */ _col(64)"RR" di as text "{hline 8}{c +}{hline 63}" local i 1 while `i' <=`strmax' { di as result `stratum'[`i'] as text _col(9)"{c |}" as result /* */ _col(11) %5.4f `drr'[`i'] /* */ _col(19) "[" as result %5.4f `drrl'[`i'] /* */ "," /* */ as result _col(28) %5.4f `drru'[`i'] "]" /* */ as result _col(37) %5.4f `prr'[`i'] /* */ _col(45) "[" as result %5.4f `prrl'[`i'] /* */ "," /* */ as result _col(54) %5.4f `prru'[`i'] "]" /* */ as result _col(64) %5.4f `rr'[`i'] local i = `i'+1 } di as text "{hline 8}{c +}{hline 63}" di as text "crude" _col(9) "{c |}" as result /* */ _col(11) %5.4f `drr0' /* */ _col(19) "[" %5.4f `drrl0' "," /* */ _col(28) %5.4f `drru0' "]" /* */ _col(37) %5.4f `prr0' /* */ _col(45) "[" %5.4f `prrl0' "," /* */ _col(54) %5.4f `prru0' "]" /* */ _col(64) %5.4f `rr0' di as text "crudenew{c |}" as result /* */ _col(11) %5.4f `drr0n' /* */ _col(19) "[" %5.4f `drrl0n' "," /* */ _col(28) %5.4f `drru0n' "]" /* */ _col(37) %5.4f `prr0n' /* */ _col(45) "[" %5.4f `prrl0n' "," /* */ _col(54) %5.4f `prru0n' "]" /* */ _col(64) %5.4f `rr0n' di as text "adjusted{c |}" as result /* */ _col(11) %5.4f `adrr' /* */ _col(19) "[" %5.4f `adrrl' "," /* */ _col(28) %5.4f `adrru' "]" /* */ _col(37) %5.4f `aprr' /* */ _col(45) "[" %5.4f `aprrl' "," /* */ _col(54) %5.4f `aprru' "]" /* */ _col(64) %5.4f `arr' di as text "{hline 8}{c BT}{hline 63}" di as text "Homogeneity test of driver RR estimates " /* */ as result _col(60) "p = " %5.4f `dpchi' di as text "Homogeneity test of passenger RR estimates " /* */ as result _col(60) "p = " %5.4f `ppchi' di as text "{hline 72}" /* now comes the second part of the big if/else loop, showing results if there is only one stratum */ } else { di local c1 = 73 - (8 + length("Pairs used = ")) di as text "Double-pair method" _col(`c1') /* */ "Pairs used = " as result %8.0g `prct' local levpc = `level'*100 di as text "Relative Risk estimates" /* */ _col(39)"Confidence interval level = " as result /* */ %4.1f `levpc' " %" di as text "{hline 72}" di as text "dRR" _col(9)"[Conf. Interval]" /* */ _col(27)"pRR" _col(35)"[Conf. Interval]" /* */ _col(53)"RR" di as text "{hline 72}" di %5.4f as result `drr0' _col(9) "[" %5.4f `drrl0' "," /* */ _col(18) %5.4f `drru0' "]" /* */ _col(27) %5.4f `prr0' /* */ _col(35) "[" %5.4f `prrl0' "," /* */ _col(44) %5.4f `prru0' "]" /* */ _col(53) %5.4f `rr0' di as text "{hline 72}" } end