Computed theoretical power for N=100 and N=200 scenarios
This commit is contained in:
437
Modules/ado/plus/m/micombine.ado
Normal file
437
Modules/ado/plus/m/micombine.ado
Normal file
@ -0,0 +1,437 @@
|
||||
*! version 1.1.1 PR 28nov2005
|
||||
/*
|
||||
History
|
||||
|
||||
1.1.1 28nov2005 eform and eform() option styles now allowed.
|
||||
nowarning option to suppress warning message about supported regression cmds.
|
||||
1.1.0 30sep2005 Generalization of supported commands (cmdchk.ado also modified).
|
||||
Version <=7 no longer supported.
|
||||
1.0.9 18apr2005 Default rowid variable becomes _i.
|
||||
If not found, take from char _dta[MI_obsid] then char _dta[mi_id].
|
||||
Default impid variable is _j. If not found, take from _dta[MI_impid].
|
||||
These changes are for future compatibility with MItools.
|
||||
1.0.8 04mar2005 Fixed problem with eform on redisplay
|
||||
1.0.7 28jan2005 Fixed problem with null model estimation
|
||||
Fixed bug with noconstant option
|
||||
1.0.6 25jan2005 e(sample) now correct for all imputations, via ereturn post.
|
||||
Add d.f. quantities from Barnard & Rubin (1999) Biometrika 86:948-955 eq (3)-(5).
|
||||
Minor additions to ereturn quantities for compatibility with misw.
|
||||
Allow null model and model only with constant for benefit of misw.
|
||||
1.0.5 16nov2004 Update calculations of quantities stored for Li et al (1991) F test.
|
||||
1.0.4 13oct2004 Change e(cmd) to `cmd', make e(cmd2)="micombine" (for use after mfx).
|
||||
Implementation of mean log likelihood and chisquare statistic saved
|
||||
(note undocumented -noclear- but v. useful option to ereturn post/estimates post).
|
||||
*/
|
||||
program define micombine, eclass
|
||||
|
||||
if _caller()<=7 {
|
||||
di as error "version 7 and earlier not supported"
|
||||
exit 9
|
||||
}
|
||||
|
||||
if replay() {
|
||||
if `"`e(cmd2)'"'!="micombine" {
|
||||
error 301
|
||||
}
|
||||
syntax[, EForm EForm2(string)]
|
||||
if "`eform2'"!="" {
|
||||
if "`eform'"!="" di as err "[eform ignored]"
|
||||
local eform eform(`eform2')
|
||||
}
|
||||
else if "`eform'"!="" local eform eform("exp(b)")
|
||||
di as text _n "Multiple imputation parameter estimates (" as res e(m) as text " imputations)"
|
||||
capture ereturn display, `eform'
|
||||
local rc=_rc
|
||||
if `rc'>0 {
|
||||
* Null model, or model with cc() only
|
||||
if `"`e(cmd)'"'!="stcox" {
|
||||
`e(cmd)' `0'
|
||||
}
|
||||
else di as text "[Null model - no estimates]"
|
||||
}
|
||||
else ereturn display, `eform'
|
||||
di as result e(N) as text " observations."
|
||||
exit
|
||||
}
|
||||
|
||||
gettoken cmd 0 : 0
|
||||
if "`cmd'"=="stpm" {
|
||||
local dist 7
|
||||
local bad 0
|
||||
}
|
||||
else {
|
||||
cmdchk `cmd'
|
||||
local cmdnotknown `s(bad)'
|
||||
/*
|
||||
dist=0 (normal), 1 (binomial), 2 (poisson), 3 (cox), 4 (glm),
|
||||
5 (xtgee), 6(ereg/weibull).
|
||||
*/
|
||||
local dist `s(dist)'
|
||||
}
|
||||
syntax [anything] [if] [in] [aw fw pw iw] , [ IMPid(string) BR CC(varlist) noCONStant ///
|
||||
DEAD(varname) DETail EForm EForm2(string) GENxb(string) LRR noWARning OBSid(string) * ]
|
||||
|
||||
if `cmdnotknown' & "`warning'"!="nowarning" {
|
||||
di as err _n "Warning: " as inp "`cmd'" as err " is not a certified regression command for micombine."
|
||||
di as err "micombine will continue mechanically, but correct results are not guaranteed."
|
||||
di as err "You must take responsibility that Rubin's rules are appropriate here." _n
|
||||
}
|
||||
|
||||
if "`eform2'"!="" {
|
||||
if "`eform'"!="" di as err "[eform ignored]"
|
||||
local eform eform(`eform2')
|
||||
}
|
||||
else if "`eform'"!="" local eform eform("exp(b)")
|
||||
|
||||
* Check for possible impid characteristic. If it does not exist use default _j
|
||||
if "`impid'"=="" {
|
||||
local impid: char _dta[MI_impid]
|
||||
if "`impid'"=="" local impid _j
|
||||
}
|
||||
cap confirm var `impid'
|
||||
if _rc {
|
||||
di as err "imputation identifier `impid' not found"
|
||||
exit 601
|
||||
}
|
||||
|
||||
* Check for possible obsid chars. If none exist use default _i
|
||||
if "`obsid'"=="" {
|
||||
local I: char _dta[MI_obsid]
|
||||
if "`I'"=="" local I: char _dta[mi_id]
|
||||
if "`I'"=="" local I _i
|
||||
}
|
||||
else local I `obsid'
|
||||
cap confirm var `I'
|
||||
if _rc {
|
||||
di as err "observation identifier `I' not found"
|
||||
exit 601
|
||||
}
|
||||
|
||||
if "`detail'"!="" {
|
||||
local detail noisily
|
||||
}
|
||||
else local detail
|
||||
|
||||
*Change here 11/15/05, commenting out the line below !! PR DELETED XIAO CHEN'S EDIT, NOV 05
|
||||
frac_cox "`dead'" `dist'
|
||||
|
||||
if "`constant'"=="noconstant" {
|
||||
if "`cmd'"=="fit" | "`cmd'"=="stcox" | "`cmd'"=="cox" {
|
||||
di as error "noconstant invalid with `cmd'"
|
||||
exit 198
|
||||
}
|
||||
}
|
||||
|
||||
*Change here 11/15/05, `dist' could be null.... !! PR DELETED XIAO CHEN'S EDIT, NOV 05
|
||||
*if "`dist'" =="7" { /* stcox, streg, stpm */
|
||||
if `dist'==7 {
|
||||
local y
|
||||
local yname _t
|
||||
local xvars `anything'
|
||||
}
|
||||
else {
|
||||
gettoken y xvars : anything
|
||||
gettoken xvars left: xvars, parse("(")
|
||||
local yname `y'
|
||||
}
|
||||
|
||||
tempvar touse
|
||||
quietly {
|
||||
marksample touse
|
||||
markout `touse' `varlist' `dead' `cc'
|
||||
if "`dead'"!="" {
|
||||
local dead "dead(`dead')"
|
||||
}
|
||||
|
||||
* Deal with weights.
|
||||
frac_wgt `"`exp'"' `touse' `"`weight'"'
|
||||
local wgt `r(wgt)'
|
||||
|
||||
tempvar J
|
||||
* Important (compatibility with mitools): ignore rows for which impid=0
|
||||
egen int `J'=group(`impid') if `touse'==1 & `impid'>0 & !missing(`impid')
|
||||
sum `J', meanonly
|
||||
local m=r(max)
|
||||
if `m'<2 {
|
||||
di as error "there must be at least 2 imputations"
|
||||
exit 198
|
||||
}
|
||||
|
||||
local nxvar: word count `xvars'
|
||||
/*
|
||||
if `nxvar'<1 {
|
||||
di as err "there must be at least one covariate"
|
||||
exit 198
|
||||
}
|
||||
*/
|
||||
local ncc: word count `cc' /* could legitimately be zero */
|
||||
local nvar=`nxvar'+`ncc' /* number of covariates in model */
|
||||
|
||||
count if `touse'==1 & `J'==1
|
||||
local nobs=r(N)
|
||||
|
||||
* Null Cox model (or model with only ccvars): fit on final imputation only, and quit
|
||||
if "`xvars'"=="" & ("`cmd'"=="cox" | "`cmd'"=="stcox") {
|
||||
if "`cmd'"=="stcox" & "`cc'"=="" {
|
||||
local options `options' estimate
|
||||
}
|
||||
`detail' `cmd' `y' `cc' if `touse'==1 & `J'==`m' `wgt', `options' `dead' `constant'
|
||||
noi `cmd'
|
||||
di as result `nobs' as text " observations."
|
||||
ereturn scalar m=`m'
|
||||
ereturn local impid `impid'
|
||||
ereturn local cmd `cmd'
|
||||
ereturn local cmd2 micombine
|
||||
exit
|
||||
}
|
||||
|
||||
* Compute model over m imputations
|
||||
tempname W Q B T QQ
|
||||
if "`genxb'"!="" {
|
||||
tempvar xb xbtmp
|
||||
gen `xb'=.
|
||||
}
|
||||
* Estimate mean LR chisquare statistic (where possible)
|
||||
tempname chi2 ell ell0 nucom
|
||||
scalar `chi2'=0
|
||||
scalar `ell'=0
|
||||
scalar `ell0'=0
|
||||
forvalues i=1/`m' {
|
||||
tempname Q`i'
|
||||
`detail' `cmd' `y' `xvars' `cc' `left' if `touse'==1 & `J'==`i' `wgt', ///
|
||||
`options' `dead' `constant'
|
||||
scalar `nucom'=e(df_r) // complete-data residual degrees of freedom
|
||||
if `nucom'==. {
|
||||
scalar `nucom'=100000
|
||||
}
|
||||
scalar `ell'=`ell'+e(ll)
|
||||
scalar `ell0'=`ell0'+e(ll_0)
|
||||
scalar `chi2'=`chi2'-2*(e(ll_0)-e(ll))
|
||||
if "`genxb'"!="" {
|
||||
predict `xbtmp' if `touse'==1 & `J'==`i', xb
|
||||
replace `xb'=`xbtmp' if `touse'==1 & `J'==`i'
|
||||
drop `xbtmp'
|
||||
}
|
||||
matrix `Q`i''=e(b)
|
||||
if `i'==1 {
|
||||
matrix `Q'=e(b)
|
||||
matrix `W'=e(V)
|
||||
}
|
||||
else {
|
||||
matrix `Q'=`Q'+e(b)
|
||||
matrix `W'=`W'+e(V)
|
||||
}
|
||||
|
||||
}
|
||||
if "`genxb'"!="" {
|
||||
sort `touse' `I' `J'
|
||||
by `touse' `I': gen `genxb'=sum(`xb')/`m' if `touse'==1
|
||||
by `touse' `I': replace `genxb'=`genxb'[_N] if _n<_N
|
||||
lab var `genxb' "Mean Linear Predictor (`m' imputations)"
|
||||
}
|
||||
matrix `Q'=`Q'/`m' /* MI param estimates */
|
||||
matrix `W'=`W'/`m'
|
||||
scalar `chi2'=`chi2'/`m'
|
||||
scalar `ell'=`ell'/`m'
|
||||
scalar `ell0'=`ell0'/`m'
|
||||
local k=colsof(`Q')
|
||||
matrix `B'=J(`k',`k',0)
|
||||
forvalues i=1/`m' {
|
||||
matrix `QQ'=`Q`i''-`Q'
|
||||
if `i'==1 {
|
||||
matrix `B'=`QQ''*`QQ'
|
||||
}
|
||||
else matrix `B'=`B'+`QQ''*`QQ'
|
||||
}
|
||||
matrix `B'=`B'/(`m'-1)
|
||||
matrix `T'=`W'+(1+1/`m')*`B' /* estimated VCE matrix */
|
||||
/*
|
||||
Relative increase in variance due to missing information (r) for
|
||||
each variable, and df and lambda, the fraction of missing information.
|
||||
All measures are unstable for low m. See Schafer (1997) p. 110.
|
||||
|
||||
Note that BIF = sqrt(T/W) = sqrt(1 + (B/W)*(1+1/m)) = sqrt(1+r)
|
||||
is the between-imputation imprecision factor, i.e. the ratio
|
||||
of the SE derived from T to the SE derived from W,
|
||||
ignoring between-imputation variation in parameter estimates.
|
||||
*/
|
||||
tempname r t lambda nu BIF
|
||||
matrix `r'=J(1,`k',0)
|
||||
matrix `lambda'=J(1,`k',0)
|
||||
matrix `nu'=J(1,`k',0)
|
||||
matrix `BIF'=J(1,`k',0)
|
||||
scalar `t'=`m'-1
|
||||
* Next few lines assign quantities for tests of individual (1 df) components of Q (=beta)
|
||||
forvalues j=1/`k' {
|
||||
matrix `r'[1,`j']=(1+1/`m')*`B'[`j',`j']/`W'[`j',`j']
|
||||
matrix `nu'[1,`j']=cond(`t'>4, 4+(`t'-4)*(1+(1-2/`t')/`r'[1,`j'])^2, `t'*(1+1/`r'[1,`j'])^2)
|
||||
matrix `lambda'[1,`j']=(`r'[1,`j']+2/(`nu'[1,`j']+3))/(`r'[1,`j']+1)
|
||||
matrix `BIF'[1,`j']=sqrt(1+`r'[1,`j']) /* = sqrt(`T'[`j',`j']/`W'[`j',`j']) */
|
||||
}
|
||||
* Next few lines assign quantities for d.f. from Barnard & Rubin 1999 B'ka 86(4): 948-955.
|
||||
tempname nutilde num nuobs gamma
|
||||
matrix `nutilde'=J(1,`k',0)
|
||||
matrix `num'=J(1,`k',0)
|
||||
matrix `nuobs'=J(1,`k',0)
|
||||
matrix `gamma'=J(1,`k',0)
|
||||
forvalues j=1/`k' {
|
||||
matrix `gamma'[1,`j']=(1+1/`m')*`B'[`j',`j']/`T'[`j',`j']
|
||||
matrix `nuobs'[1,`j']=((`nucom'+1)/(`nucom'+3))*`nucom'*(1-`gamma'[1,`j'])
|
||||
matrix `num'[1,`j']=(`m'-1)*`gamma'[1,`j']^-2
|
||||
matrix `nutilde'[1,`j']=1/((1/`num'[1,`j']+1/`nuobs'[1,`j']))
|
||||
}
|
||||
* use all varnames
|
||||
local names: colnames(`Q1')
|
||||
matrix colnames `r'=`names'
|
||||
matrix colnames `nu'=`names'
|
||||
matrix colnames `lambda'=`names'
|
||||
matrix colnames `BIF'=`names'
|
||||
|
||||
matrix colnames `gamma'=`names'
|
||||
matrix colnames `nuobs'=`names'
|
||||
matrix colnames `num'=`names'
|
||||
matrix colnames `nutilde'=`names'
|
||||
|
||||
* Li, Raghunathan & Rubin (1991) estimates of T and nu1
|
||||
* for F test of Q=0 on k,nu1 degrees of freedom
|
||||
tempname r1 t1 BW TLRR
|
||||
matrix `BW'=`B'*syminv(`W')
|
||||
scalar `r1'=trace(`BW')*(1+1/`m')/`k'
|
||||
matrix `TLRR'=`W'*(1+`r1')
|
||||
scalar `t1'=`k'*(`m'-1)
|
||||
matrix colnames `Q'=`names'
|
||||
matrix rownames `T'=`names'
|
||||
matrix colnames `T'=`names'
|
||||
matrix rownames `B'=`names'
|
||||
matrix colnames `B'=`names'
|
||||
matrix rownames `TLRR'=`names'
|
||||
matrix colnames `TLRR'=`names'
|
||||
|
||||
}
|
||||
di as text _n "Multiple imputation parameter estimates (`m' imputations)"
|
||||
if "`lrr'"!="" {
|
||||
di as text "[Using Li-Raghunathan-Rubin (LRR) estimate of VCE matrix]"
|
||||
ereturn post `Q' `TLRR', depname(`yname') obs(`nobs') esample(`touse') noclear
|
||||
ereturn matrix T `T'
|
||||
}
|
||||
else {
|
||||
ereturn post `Q' `T', depname(`yname') obs(`nobs') esample(`touse') noclear
|
||||
ereturn matrix TLRR `TLRR'
|
||||
}
|
||||
if "`br'"=="" {
|
||||
ereturn display, `eform'
|
||||
di as result `nobs' as text " observations."
|
||||
}
|
||||
ereturn matrix B `B'
|
||||
ereturn matrix W `W'
|
||||
ereturn matrix r `r'
|
||||
ereturn matrix nu `nu'
|
||||
ereturn matrix lambda `lambda'
|
||||
ereturn matrix BIF `BIF'
|
||||
|
||||
* Quantities for calculating df `nutilde' according to Barnard & Rubin (1999)
|
||||
ereturn matrix gamma `gamma'
|
||||
ereturn matrix nuobs `nuobs'
|
||||
ereturn matrix num `num'
|
||||
ereturn matrix nutilde `nutilde'
|
||||
|
||||
ereturn scalar r1=`r1'
|
||||
ereturn scalar nu1=cond(`t1'>4, 4+(`t1'-4)*(1+(1-2/`t1')/`r1')^2, 0.5*`t1'*(1+1/`k')*(1+1/`r1')^2)
|
||||
ereturn scalar m=`m'
|
||||
ereturn scalar chi2=`chi2'
|
||||
ereturn scalar ll=`ell'
|
||||
ereturn scalar ll_0=`ell0'
|
||||
ereturn local eform `eform'
|
||||
ereturn local impid `impid'
|
||||
ereturn local cmd `cmd'
|
||||
ereturn local cmd2 micombine
|
||||
if "`br'"!="" {
|
||||
display_t
|
||||
di as result `nobs' as text " observations."
|
||||
}
|
||||
end
|
||||
|
||||
program define display_t
|
||||
* Display results with t-statistics estimated according to Barnard & Rubin (1999)
|
||||
tempname V Q nu
|
||||
matrix `V'=e(V)
|
||||
matrix `Q'=e(b)
|
||||
matrix `nu'=e(nutilde)
|
||||
local yname `e(depvar)'
|
||||
local xs: colnames `Q'
|
||||
local k=colsof(`Q')
|
||||
di as text _n "Intervals and inference based on d.f. from Barnard & Rubin (1999)"
|
||||
di as txt "{hline 13}{c TT}{hline 64}"
|
||||
local t0 = abbrev("`yname'",12)
|
||||
if `"`e(eform)'"'!="" {
|
||||
local tt "Odds Ratio"
|
||||
}
|
||||
else {
|
||||
local tt " Coef."
|
||||
}
|
||||
|
||||
#delimit ;
|
||||
di as text
|
||||
%12s "`t0'" _col(14)"{c |}`tt' Std. Err. t P>|t| [$S_level% Conf. Intvl] MI.df"
|
||||
_n "{hline 13}{c +}{hline 64}" ;
|
||||
#delimit cr
|
||||
tempname df mn se t p invt l u
|
||||
forvalues i=1/`k' {
|
||||
local x: word `i' of `xs'
|
||||
if "`x'"!="_cons" {
|
||||
local fmt : format `x'
|
||||
if substr("`fmt'",-1,1)=="f" {
|
||||
local fmt="%8."+substr("`fmt'",-2,2)
|
||||
}
|
||||
else if substr("`fmt'",-2,2)=="fc" {
|
||||
local fmt="%8."+substr("`fmt'",-3,3)
|
||||
}
|
||||
else local fmt "%8.0g"
|
||||
local fmt`i' `fmt'
|
||||
}
|
||||
else local fmt "%8.0g"
|
||||
scalar `df' =`nu'[1,`i']
|
||||
scalar `mn' = `Q'[1,`i']
|
||||
scalar `se' = sqrt(`V'[`i',`i'])
|
||||
scalar `t' = `mn'/`se'
|
||||
scalar `p' = 2* ttail(`df', abs(`t'))
|
||||
scalar `invt' = invttail(`df', (1-$S_level/100)/2)
|
||||
scalar `l' = `mn' - `invt'*`se'
|
||||
scalar `u' = `mn' + `invt'*`se'
|
||||
if `"`e(eform)'"'!="" {
|
||||
scalar `mn' = exp(`mn')
|
||||
scalar `se' = `mn'*`se'
|
||||
scalar `l' = exp(`l')
|
||||
scalar `u' = exp(`u')
|
||||
}
|
||||
if `df'>99999 {
|
||||
local fmtdf %9.2e
|
||||
}
|
||||
else local fmtdf %9.2f
|
||||
di as text /*
|
||||
*/ %12s abbrev("`x'",12) _col(14) "{c |}" /*
|
||||
*/ _col(17) as res `fmt' `mn' /*
|
||||
*/ _col(27) `fmt' `se' /*
|
||||
*/ _col(36) %7.2f `t' /*
|
||||
*/ _col(42) %7.3f `p' /*
|
||||
*/ _col(52) `fmt' `l' /*
|
||||
*/ _col(61) `fmt' `u' /*
|
||||
*/ _col(70) `fmtdf' `df'
|
||||
}
|
||||
di as text "{hline 13}{c BT}{hline 64}"
|
||||
end
|
||||
|
||||
program define chkrowid, sclass
|
||||
local I: char _dta[mi_id]
|
||||
if "`I'"=="" {
|
||||
di as error "no row-identifier variable found - data may have incorrect format"
|
||||
exit 198
|
||||
}
|
||||
cap confirm var `I'
|
||||
local rc=_rc
|
||||
if `rc' {
|
||||
di as error "row-identifier variable `I' not found"
|
||||
exit `rc'
|
||||
}
|
||||
sret local I `I'
|
||||
end
|
Reference in New Issue
Block a user