📄 mhodds.ado
字号:
*! version 6.1.9 17mar2005
program define mhodds, rclass
version 6, missing
syntax varlist(min=2) [if] [in] [fweight] [, Binomial(string) /*
*/ Compare(string) BY(string) Level(cilevel) ]
marksample touse, strok
tokenize `varlist'
tempvar d order e
/* checks that weight and binomial are not both present */
if "`binomial'"!="" & "`weight'"!="" {
di in re "weight not allowed with binomial() option"
exit 198
}
/* chk if response is coded 0/1 for individual or freq records */
qui gen int `d'=`1' if `touse'
if "`binomial'" == "" {
capture assert `d'==0 | `d'==1 if `touse'
if _rc~=0 {
di in re "Response `1' not coded 0/1"
exit 198
}
}
capture confirm string variable `2'
if _rc==0 {
noi di in red "nonnumeric variable `2' not allowed"
exit 198
}
qui gen `e'=`2' if `touse'
qui gen int `order'=_n
local ne = "`2'"
local abne = abbrev("`ne'",12)
/* puts variables to be controlled for in local macro str */
local str=""
while "`3'" != "" {
local str="`str' `3'"
mac shift
}
/* if !compare & 2 levels for xvar: set compare & use the 2 levels */
if "`compare'" == "" {
qui inspect `e'
if r(N_unique) == 2 {
local compare "compare"
quietly summarize `e' if `touse', meanonly
local grp1 = r(max)
local grp2 = r(min)
}
}
else {
tokenize "`compare'", parse(",")
local grp1 `1'
local grp2 `3'
}
* sets titles
if "`compare'" != "" {
if "`str'" != "" {
local t2:word count `str'
TITle `t2' `str'
di in gr _n "Mantel-Haenszel estimate of the odds ratio"
di in gr /*
*/ "Comparing `abne'==`grp1' vs. `abne'==`grp2'," /*
*/ " controlling for `r(t2)'"
}
else {
di in gr _n /*
*/ "Maximum likelihood estimate of the odds ratio"
di in gr "Comparing `abne'==`grp1' vs. `abne'==`grp2'"
}
}
else {
di in gr _n "Score test for trend of odds with `abne'"
if "`str'" != "" {
local t2:word count `str'
TITle `t2' `str'
di in gr "controlling for `r(t2)'"
}
}
if "`by'" != "" {
local bycnt: word count `by'
if `bycnt'>3 {
di in red "only 3 by() variables allowed"
exit 198
}
unabbrev `by'
local by="`s(varlist)'"
di in gr "by `by'"
}
* sets the variable h for controls
tempvar h
if "`binomial'" == "" {
qui gen int `h' = 1 - `d' if `touse'
}
else {
qui gen int `h' = `binomial' - `d' if `touse'
}
tempvar wt
qui gen long `wt' = 1 if `touse'
if "`weight'" != "" {
qui replace `wt' `exp' if `touse'
}
capture noisily {
/* sets variable to index strata which is 1 for no strata */
tempvar strata
if "`str'" != "" {
qui egen int `strata' = group(`str') if `touse'
}
else {
qui gen int `strata' = 1 if `touse'
}
tempvar d1 d2 h1 h2 p1 p2 dt ht pt q r u v rr ef sm
* If compare not blank then use odds ratios
if "`compare'" != "" {
tempvar last
qui replace `touse'=0 if `e' != `grp1' & `e' != `grp2'
sort `touse' `strata' `by'
qui by `touse' `strata' `by': /*
*/ gen double `d1'=sum(cond(`e'==`grp1',`d',0)*`wt') /*
*/ if `touse'
qui by `touse' `strata' `by': /*
*/ gen double `d2'=sum(cond(`e'==`grp2',`d',0)*`wt') /*
*/ if `touse'
qui by `touse' `strata' `by': /*
*/ gen double `h1'=sum(cond(`e'==`grp1',`h',0)*`wt') /*
*/ if `touse'
qui by `touse' `strata' `by': /*
*/ gen double `h2'=sum(cond(`e'==`grp2',`h',0)*`wt') /*
*/ if `touse'
qui gen byte `last'=0
qui by `touse' `strata' `by': /*
*/ replace `last'=1 if _n == _N & `touse'
qui gen double `dt' = `d1' + `d2' if `last'==1
qui gen double `ht' = `h1' + `h2' if `last'==1
qui gen double `p1' = `h1' + `d1' if `last'==1
qui gen double `p2' = `h2' + `d2' if `last'==1
qui gen double `pt' = `p1' + `p2' if `last'==1
qui gen double `q' = `d1'*`h2'/`pt' if `last'==1
qui gen double `r' = `d2'*`h1'/`pt' if `last'==1
qui gen double `u' = `q' - `r' if `last'==1
qui gen double `v' = /*
*/ `p1'*`p2'*`dt'*`ht'/((`pt'-1)*(`pt'^2)) if `last'==1
*qui replace `v'=. if `r'==0 | `q'==0
tempname cl
qui count if `last'==1
scalar `cl'=r(N)
qui count if `v'>0 & `v'< . & `last'==1
if r(N)<`cl' {
noi di _n in gr "note: only " r(N) /*
*/ " of the " `cl' " strata " /*
*/ "formed in this analysis contribute" _n /*
*/ " information about the effect of the explanatory variable"
}
drop `h1' `h2' `d1' `d2' `ht' `dt' `p1' `p2' `pt'
/* if by not blank then do homogeneity test */
if "`by'" != "" {
sort `touse' `by'
qui by `touse' `by': replace `q' = /*
*/ sum(`q') if `touse'
qui by `touse' `by': replace `r' = /*
*/ sum(`r') if `touse'
qui by `touse' `by': replace `u' = /*
*/ sum(`u') if `touse'
qui by `touse' `by': replace `v' = /*
*/ sum(`v') if `touse'
tempvar last
qui by `touse' `by': /*
*/ gen byte `last'=1 if _n == _N & `touse'
local N1 = _N + 1
qui set obs `N1'
qui replace `last'=1 if _n==_N
qui gen double `sm' = sum(`q') if `last'==1
qui replace `q' = `sm' if _n == _N
qui replace `sm' = sum(`r') if `last'==1
qui replace `r' = `sm' if _n == _N
qui replace `sm' = sum(`u') if `last'==1
qui replace `u' = `sm' if _n == _N
qui replace `sm' = sum(`v') if `last'==1
qui replace `v' = `sm' if _n == _N
local Q = `q'[_N]
local R = `r'[_N]
qui replace `sm' = /*
*/ ((`q'*`R' - `r'*`Q')^2)/(`Q'*`R'*`v') /*
*/ if _n < _N & `last'==1
qui replace `sm' = 0 if _n == _N | `v' == 0
qui inspect `sm'
local hdf = r(N_pos)
qui replace `sm' = sum(`sm') if `last'==1
local het = `sm'[_N]
}
else {
qui replace `q' = sum(`q')
qui replace `r' = sum(`r')
qui replace `u' = sum(`u')
qui replace `v' = sum(`v')
qui replace `last'=cond(_n==_N, 1, .)
}
qui gen double `rr' =`q'/`r' if `last'==1
qui gen double `ef'= exp(invnorm(`level'*0.005 + 0.5) /*
*/ * sqrt(`v'/(`q'*`r'))) if `last'==1
} /* end of compare!="" */
/* if compare is blank then use trend with xvar*/
else {
sort `touse' `strata' `by'
qui by `touse' `strata' `by': /*
*/ gen double `dt'=sum(`d'*`wt') if `touse'
qui by `touse' `strata' `by': gen double `pt'= /*
*/ sum((`d'+`h')*`wt') if `touse'
qui by `touse' `strata' `by': /*
*/ gen double `d1'=sum(`d'*`e'*`wt') /*
*/ if `touse'
qui by `touse' `strata' `by': gen double `p1'= /*
*/ sum((`d'+`h')*`e'*`wt') if `touse'
qui by `touse' `strata' `by': gen double `p2' = /*
*/ sum((`d'+`h')*`e'*`e'*`wt') if `touse'
tempvar last
qui by `touse' `strata' `by': /*
*/ gen byte `last'=1 if _n == _N & `touse'
qui gen double `u' = `d1' -(`dt'*`p1'/`pt') if `last'==1
qui gen double `v' = `dt'*(`pt'-`dt')/*
*/ *(`p2'-`p1'*`p1'/`pt')/(`pt'*(`pt'-1)) if `last'==1
tempname cl
qui count if `last'==1 & `touse'
scalar `cl'=r(N)
qui count if `v'>0 & `v'< . & `last'==1
if r(N)<`cl' {
noi di _n in gr "note: only " /*
*/ r(N) " of the " `cl' " strata " /*
*/ "formed in this analysis contribute" _n /*
*/ " information about the "/*
*/"effect of the explanatory variable"
}
/* if by is not blank do homogeneity test */
if "`by'" != "" {
tempvar last
sort `touse' `by'
qui by `touse' `by': replace `u' = sum(`u') /*
*/ if `touse'
qui by `touse' `by': replace `v' = sum(`v') /*
*/ if `touse'
qui by `touse' `by': gen byte `last'=1 /*
*/ if _n == _N & `touse'
local N1 = _N + 1
qui set obs `N1'
qui replace `last'=1 if _n==_N
qui gen double `sm' = sum(`u') if `last'==1
qui replace `u' = `sm' if _n == _N
qui replace `sm' = sum(`v') if `last'==1
qui replace `v' = `sm' if _n == _N
qui replace `sm' = `u'^2/`v' if `last'==1
qui replace `sm' = - `sm' if _n == _N
qui inspect `sm'
local hdf = _result(4)
qui replace `sm' = sum(`sm')
qui local het = `sm'[_N]
}
else {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -