*! version 1.1.0 28aug2000 *! enhanced table interface to cs for more than 2 groups *! authors Jens M. Lauritsen & Thomas J. Steichen program define csjl version 6 syntax varlist(min=2 max=2 num) [if] [in] [fweight] [, /* */ rr rd at TYpe(string) Ref(int 1) Case(int 2) /* */ MISsing Level(int $S_level) by(varlist) SUBTab /* */ SUBPct TABle TABPct CHI EXact TOtal DEC(int 2) ] tokenize `varlist' local xdat1 "`1'" local xdat2 "`2'" if "`exp'" != "" {local wtopt "[fw `exp']"} local chitab = "`chi'" if "`exact'" == "exact" { local chi = "" } if "`type'" == "" { if "`rr'" != "" { local type = " rr"} if "`rd'" != "" { local type = "`type'" + " rd"} if "`at'" != "" { local type = "`type'" + " at"} } else { local wctyp: word count "`type'" local wc = 1 while `wc' <= `wctyp' { local wty: word `wc' of `type' if "`wty'" != "rr" & "`wty'" != "rd" & "`wty'" != "at" { di _n in re "type() has invalid value: " in ye "`wty'" exit } local wc = `wc' + 1 } } local stype = trim("`type'" + " `chi'" + " `exact'") local by = cond("`by'" == "", "ovr12345", "ovr12345" + " `by'") if "`stype'" == "" { di _n in bl " Warning: no risk estimates specified," _c di in wh " rr" in bl " assumed" local stype = "rr" } local lb: var label `xdat1' di _n " `xdat1' " _col(12) "`lb'" local lb: var label `xdat2' di " `xdat2' " _col(12) "`lb'" * show overall tables if desired: if "`table'" != "" { di _n in ye "table is:" _c noi tabulate `xdat2' `xdat1' `if' `in' `wtopt', `missing' `chitab' } if "`tabpct'" != "" { di _n in ye "table with row percentage is:" _c noi tab `xdat2' `xdat1' `if' `in' `wtopt', `chitab' row `missing' } * main by loop * create heading for overall table: * make a subtable for each level of a by variable: while "`by'" ~= "" { * find out which current by variable (note overall table called ovr12345). if index("`by'"," ") > 0 { local byvar = substr("`by'",1,index("`by'"," "))} else {local byvar = substr("`by'",1,length("`by'"))} local byvars =trim("`byvar'") *get type for -byvar- cap confirm string var `byvar' *if string, temp encode if _rc == 0 { tempvar byvare encode `byvar', gen(`byvare') local byvar "`byvare'" } *diminish by for next table: local by = cond(index("`by'"," ") > 0,trim(substr("`by'",index("`by'"," ")+1,20)),"") if trim("`byvar'") == "ovr12345" { local byj = 1 local outtab = cond("`if'" == "", "","`if'") } else { /* select create matrix with levels of byvargrp */ qui tab `byvar' `if' `in' `wtopt', matrow(byrow) `missing' local byj = rowsof(byrow) local byt: val l `byvar' * which label value is first, 0 or 1 ? local bylabn = 0 if "`byt'" != "" { local bylab: label `byt' 0 8 if trim("`bylab'") == "0" { local bylabn = 1 } } } local bylist local byi = 1 while `byi' <= `byj' { if trim("`byvar'") == "ovr12345" { local missing = cond("`missing'" == "","","missing") qui tab `xdat2' `xdat1' `in' `if' `wtopt', matcell(tabel) matrow(colval) `missing' local byi = `byi' + 2 } else { if "`byt'" != "" { local bylab: label `byt' `bylabn' 8 } else { local bylab = byrow[`byi',1] } if byrow[`byi',1] == . { local bylab = byrow[`byi',1] } local byval = byrow[`byi',1] local byif = cond(trim("`if'") == "","if ","`if' & ") + "(`byvar' == `byval' )" qui tab `xdat2' `xdat1' `in' `byif' `wtopt', matcell(tabel) matrow(colval) `missing' if "`bylist'" == "" & "`byvar'" != "ovr12345" { local lb: var label `byvars' di _n in gr "by " in ye "`byvars' (`lb')" local bylist = "listed" } di _n in gr " `byvars'" in ye " == " in gr "`bylab'" local byi = `byi' + 1 local bylabn = `bylabn' + 1 } local mx2 = rowsof(tabel) local mx1 = colsof(tabel) * check approprateness of variables and types of output: if `mx1' != 2 { di in yel " insufficient data." } else { local ref = cond(`ref' > `mx2',`mx2',`ref') local case = cond(`case' != 2, min(`case',2),2) if "`subtab'" != "" & trim("`byvar'") != "ovr12345" { di _n in ye "table is:" _c noi tab `xdat2' `xdat1' `byif' `in' `wtopt', `missing' `chitab' } if "`subpct'" != "" & trim("`byvar'") != "ovr12345" { di _n in ye "table with row percentage is:" _c noi tab `xdat2' `xdat1' `byif' `in' `wtopt', `chitab' row `missing' } * list subtable by categories of stratify variable: * make table: local i = rowsof(tabel) matrix col = J(`i',1,0) matrix row = J(2,1,0) * create sums local i = 0 while `i' < `mx2' { local i = `i' + 1 mat col[`i',1] = tabel[`i',1] + tabel[`i',2] mat row[1,1] = row[1,1] + tabel[`i',1] mat row[2,1] = row[2,1] + tabel[`i',2] } * ready to create results. matrix outrr = J(`i',1,0) matrix lowrr = J(`i',1,0) matrix highrr = J(`i',1,0) matrix outrd = J(`i',1,0) matrix lowrd = J(`i',1,0) matrix highrd = J(`i',1,0) matrix outat = J(`i',1,0) matrix lowat = J(`i',1,0) matrix highat = J(`i',1,0) matrix Chi = J(`i',1,0) matrix p_chi = J(`i',1,0) local i = 1 while `i' <= `mx2' { if `i' != `ref' { local a = tabel[`i', `case'] local b = tabel[`ref',`case'] local c = cond(`case' == 1, tabel[`i',2], tabel[`i',1]) local d = cond(`case' == 1, tabel[`ref',2], tabel[`ref',1]) if tabel[`i',1] > 0 & tabel[`i',2] > 0 { qui csi `a' `b' `c' `d', `exact' level(`level') if r(rr) != . { mat outrr[`i',1] = r(rr) mat lowrr[`i',1] = r(lb_rr) mat highrr[`i',1] = r(ub_rr) mat outrd[`i',1] = r(rd) mat lowrd[`i',1] = r(lb_rd) mat highrd[`i',1] = r(ub_rd) mat outat[`i',1] = r(afe) mat lowat[`i',1] = r(lb_afe) mat highat[`i',1] = r(ub_afe) } if "`exact'" == "" { mat Chi[`i',1] = r(chi2) mat p_chi[`i',1] = r(p) } else { mat Chi[`i',1] = 0 mat p_chi[`i',1] = r(p_exact) } if `b' == 0 { mat p_chi[`i',1] = -1.0 } } else { mat outrr[`i',1] = 0 mat lowrr[`i',1] = 0 mat highrr[`i',1] = 0 mat outrd[`i',1] = 0 mat lowrd[`i',1] = 0 mat highrd[`i',1] = 0 mat outat[`i',1] = 0 mat lowat[`i',1] = 0 mat highat[`i',1] = 0 mat Chi[`i',1] = 0 mat p_chi[`i',1] = -1.0 } } local i = `i' + 1 } * output table * step through levels of the table * find size of largest estimate: local i = 0 local sizrr = 0 local sizrd = 0 local sizat = 0 local sizrrm = 0 local sizrdm = 0 local sizatm = 0 while `i' < `mx2' { local i = `i' + 1 local sizrr = max(length(trim(string(int(highrr[`i',1])))),`sizrr') local sizrd = max(length(trim(string(int(highrd[`i',1])))),`sizrd') local sizat = max(length(trim(string(int(highat[`i',1])))),`sizat') if `sizrrm' == 0 { local sizrrm = cond(lowrr[`i',1] < 0,1,0) } if `sizrdm' == 0 { local sizrdm = cond(lowrd[`i',1] < 0,1,0) } if `sizatm' == 0 { local sizatm = cond(lowat[`i',1] < 0,1,0) } } local sizrr = max(5, `sizrr' + `dec' + 1 + `sizrrm') local sizrd = max(5, `sizrd' + `dec' + 1 + `sizrdm') local sizat = max(5, `sizat' + `dec' + 1 + `sizatm') local fmtrr = "%`sizrr'.`dec'f" local fmtrd = "%`sizrd'.`dec'f" local fmtat = "%`sizat'.`dec'f" * conditional output of header if trim("`byvar'") == "ovr12345" | "`subtab'" != "" | "`subpct'" != "" { top 15 `level' "`stype'" `xdat1' `xdat2' `sizrr' `sizrd' `sizat' `dec' if length(trim("`by'")) > 0 {di in gr "unstratified"} } * label: local vallab: value label `xdat2' local i = 0 while `i' < `mx2' { local i = `i' + 1 local valnum = colval[`i',1] if "`vallab'" != "" { local labx: label `vallab' `valnum' 12 } else { local labx = colval[`i',1] } di in ye %12s "`labx'" _col(15) _c * counts: di in ye %6.0f col[`i',1] %8.0f tabel[`i',`case'] " " _c if `i' == `ref' { di in ye " ref. group" _c } * user specified outcome measures, when #cases > 0: if p_chi[`i',1] == -1 { di " insufficient data" } else { parse "`stype'", parse(" ") while "`1'" ~= "" { if index("`1'","rr") > 0 { estout `fmtrr' outrr[`i',1] lowrr[`i',1] highrr[`i',1] `i' `ref' } if index("`1'","rd") > 0 { estout `fmtrd' outrd[`i',1] lowrd[`i',1] highrd[`i',1] `i' `ref' } if index("`1'","at") > 0 { estout `fmtat' outat[`i',1] lowat[`i',1] highat[`i',1] `i' `ref' } if `i' != `ref' { if index("`1'","chi") > 0 { di " " %5.1f Chi[`i',1] %7.3f p_chi[`i',1] _c } if "`1'" == "exact" { di " " %7.3f p_chi[`i',1] _c } } macro shift } di " " } } if "`total'" != "" { local x = (row[1,1] + row[2,1] ) di in ye %12s "totals" _col(15) in ye %6.0f `x' %8.0f row[`case',1] } } } /* end of bygroup level */ } /* end of current by variable */ line $S_line if $S_line > 79 & "$S_csw" != "Y" { di in bl "You can define a wider line format with the commands: " in wh _n /* */ "set log linesize $S_line " _n "set display linesize $S_line" qui push set log linesize $S_line qui push set display linesize $S_line global S_csw = "Y" } global S_line end program define estout, rclass if `5' != `6' { di " " `1' `2' " " `1' `3' " " `1' `4' _c } end program define line di in gr _dup(`1') "-" end program define top, rclass * write out first line of table * idea is to let user decide sequence of estimates or tests: local tab = `1' local lev = `2' local ty = "`3'" local Y = "`4'" local X = "`5'" local srr = `6' local srd = `7' local sat = `8' local dec = `9' di _n " Outcome: `Y' " _col(34) _c local varno: word count `ty' local i = 34 parse "`ty'", parse(" ") while "`1'" ~= "" { if index("`1'","rr") > 0 { local s = (`srr' + 1) * 3 - 10 local t = int(`s'/2) di _dup(`t') " " _c di in gr "Risk Ratio" _c local t = `s' - `t' di _dup(`t') " " _c local i = `i' + `s' + 10 } if index("`1'","rd") > 0 { local s = (`srd' + 1) * 3 - 15 local t = int(`s'/2) di _dup(`t') " " _c di in gr "Risk Difference" _c local t = `s' - `t' di _dup(`t') " " _c local i = `i' + `s' + 15 } if index("`1'","at") > 0 { local s = (`srd' + 1) * 3 - 17 local t = int(`s'/2) di _dup(`t') " " _c di in gr "Attributable Risk" _c local t = `s' - `t' di _dup(`t') " " _c local i = `i' + `s' + 17 } if index("`1'","ex") > 0 { local i = `i' + 10 } if index("`1'","chi") > 0 { local i = `i' + 14 } macro shift } di " " line `i' * column headers: di in gr _col(3) "`X'" _col(`tab') " N cases " _c parse "`ty'", parse(" ") while "`1'" ~= "" { if index("`1'","rr") > 0 { local s = `srr' - `dec' if `s' > 0 { di _dup(`s') " " _c } di in gr "`1'" _c local s = `dec' if `s' > 0 { di _dup(`s') " " _c } di in gr "[" _c local s = 2 * (`srr' + 1) - 8 - 1 local t = int(`s'/2) if `t' > 0 { di _dup(`t') " " _c } di in gr "`lev'% CI" _c local t = `s' - `t' if `t' > 0 { di _dup(`t') " " _c } di in gr "]" _c } if index("`1'","rd") > 0 { local s = `srd' - `dec' if `s' > 0 { di _dup(`s') " " _c } di in gr "`1'" _c local s = `dec' if `s' > 0 { di _dup(`s') " " _c } di in gr "[" _c local s = 2 * (`srd' + 1) - 8 - 1 local t = int(`s'/2) if `t' > 0 { di _dup(`t') " " _c } di in gr "`lev'% CI" _c local t = `s' - `t' if `t' > 0 { di _dup(`t') " " _c } di in gr "]" _c } if index("`1'","at") > 0 { local s = `sat' - `dec' if `s' > 0 { di _dup(`s') " " _c } di in gr "`1'" _c local s = `dec' if `s' > 0 { di _dup(`s') " " _c } di in gr "[" _c local s = 2 * (`sat' + 1) - 8 - 1 local t = int(`s'/2) if `t' > 0 { di _dup(`t') " " _c } di in gr "`lev'% CI" _c local t = `s' - `t' if `t' > 0 { di _dup(`t') " " _c } di in gr "]" _c } if index("`1'","exact") > 0 { di in gr " exact p " _c } else if index("`ty'","exact") == 0 & index("`1'","chi") > 0 { di in gr " Chi2 p " _c } macro shift } di " " line `i' global S_line = `i' end