You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

917 lines
24 KiB
Plaintext

*! v2.6.1 Roger Harbord 4 Nov 2008
program define metareg, eclass byable(recall)
version 7
if replay() {
if "`e(cmd)'" !="metareg" {
error 301 /* last estimates not found */
}
if _by() {
error 190 /* request may not be combined with by */
}
Display `0'
exit
}
syntax varlist(min=1 numeric) [if] [in] , [ /*
*/ wsse(varname numeric) /*
*/ EForm /*
*/ NOCONStant /*
*/ MM /*
*/ REML /*
*/ EB /*
*/ Knapphartung /*
*/ z /* standard normal w/o K-H modification to variance
*/ Level(passthru) /*
*/ PERMute(string) /*
*/ Graph /* produce a bubble plot
*/ RAndomsize /* marker size according to random-effects weights
*/ TAU2test /* tests for tau2=0 residual het test
*/ LOg /* maximize_option
*/ TOLerance(real 1e-6) /* maximize_option also used by eb method
*/ ITERate(integer 100) /* maximize_option - default 16000 is too large!
*/ wsvar(varname numeric)/* undoc'd, for compat with v1 ( wsvar = wsse^2 )
*/ bsest(string) /* undoc'd, for compat with v1
*/ tdist /* undoc'd, use t-distib w/o K-H variance mod'n
*/ ORIGinal /* undoc'd, use version 1 (metareg_orig)
*/ LRtau2 /* undoc'd, for compat with v.2.2 on SSC
*/ NOITer /* passed through to metareg_orig
*/ NOTAUComp /* no comparison of tau2 with constant-only model;
for use by permute() option
*/ * /* other `options', parsed by -mlopts-
*/ ]
marksample touse
tokenize `varlist'
local y `1' /* study estimate */
qui count if `touse'
local nobs = r(N)
if r(N) == 0 {
error 2000 /* no observations */
}
if r(N) <= `: word count `*'' {
error 2001 /* insufficient observations */
}
macro shift 1
_rmcoll `*' if `touse', `noconstant'
local xvars `r(varlist)'
mlopts mlopts, `options' iterate(`iterate') /* Parse maximize_options */
if "`wsse'"=="" & "`wsvar'"=="" {
di as error "wsse() option required"
exit 100
}
if "`wsse'"!="" & "`wsvar'"!="" {
di as error "options wsse() and wsvar() cannot both be specified"
exit 198
}
if "`wsse'"!="" {
capture assert `wsse' > 0 if `touse'
if _rc {
di as error "zero or negative wsse() not allowed"
exit 499
}
tempvar wsvar
qui gen `wsvar' = `wsse'^2 if `touse'
}
if "`wsvar'"!="" {
capture assert `wsvar' > 0 if `touse'
if _rc {
di as error "zero or negative wsvar() not allowed"
exit 499
}
}
if "`noconstant'"!="" {
/* local nvar : word count `varlist' */
if `: word count `varlist'' == 1 {
di as error "independent variables required with " /*
*/ "noconstant option"
exit 102
}
}
local wc : word count "`mm' `reml' `eb'"
if `wc' > 1 {
di as error "Only one of options mm, reml and eb can be specified"
exit 198
}
local wc : word count "`mm' `reml' `eb' `bsest'"
if `wc' > 1 {
di as error "Option bsest() cannot be used with options mm, reml or eb"
exit 198
}
if "`bsest'"!="reml" & "`bsest'"!="ml" & "`bsest'"!="eb" /*
*/ & "`bsest'"!="mm" & "`bsest'"!="" {
di as error "Between study variance estimation method invalid:"
di as error "should be either reml, ml, eb or mm"
exit 198
}
if "`bsest'" == "" {
if "`mm'" != "" | "`permute'" != "" { /* MM is default with permute */
local bsest "mm"
}
else if "`eb'" != "" {
local bsest "eb"
}
else { /* REML is default otherwise */
local bsest "reml"
}
}
if "`bsest'" =="ml" {
di as text /*
*/ "Option bsest(ml) not supported by version 2 of metareg."
di as text "Calling version 1.06 (sbe23):" _n(1)
metareg_orig `0'
exit
}
if "`knapphartung'" !="" & "`z'" != "" {
di as error "Options knapphartung and z cannot both be specified"
exit 198
}
if "`tdist'" != "" & ( "`z'" != "" | "`knapphartung'" !="" ) {
di as error "Option t cannot be specified with options knapphartung or z"
exit 198
}
if "`original'" =="original" {
di as text "Calling metareg version 1.06 (sbe23):" _n(1)
metareg_orig `0'
exit
}
if "`log'"=="" {
local log "nolog"
}
if "`lrtau2'" != "" {
local tau2test tau2test
}
if "`permute'" != "" {
if "`xvars'" == "" {
di as error "Option permute() requires at least one covariate"
exit 198
}
Permute, y(`y') xvars(`xvars') wsvar(`wsvar') permute(`permute') ///
nobs(`nobs') `noconstant' ///
bsest(`bsest') `knapphartung' `z' ///
level(`level') touse(`touse')
exit
}
/*** begin main code ***/
tempvar w hat v resid
tempname remll_c remll sumw tau2 tau2mm b V Q df_Q tau2_0
quietly {
/** (get starting values using) method-of-moments **/
gen `w'=1/`wsvar' if `touse'
summ `w' if `touse', meanonly
scalar `sumw'=r(sum)
/* use regress not vwls so can predict hat */
regress `y' `xvars' [iw=`w'] if `touse', `noconstant'
predict `hat' if `touse', hat
/* H_ii where H = X(X'WX)^{-1}X', W=diag(w) */
replace `hat'=`hat'*`w'^2 if `touse' /* Tr( WX(X'WX)^{-1}X'W ) */
/* iweights mess up residual df so compute it : */
scalar `df_Q' = `nobs' - e(df_m) - ("`noconstant'" == "")
scalar `Q' = e(rss)
summ `hat' if `touse', meanonly
scalar `tau2' = (`Q' - `df_Q') / ( `sumw' - r(sum))
/* truncate at zero */
scalar `tau2' = max(`tau2', 0)
/* Fit constant-only model to compare tau2
NB can't compare different fixed-effect models using REML log-L */
if "`noconstant'" == "" & "`notaucomp'"=="" & "`xvars'" != "" {
metareg `y' if `touse', wsvar(`wsvar') bsest(`bsest') notaucomp
scalar `tau2_0' = e(tau2)
}
} /* end quietly */
if "`bsest'" == "reml" { /* *** REML start *** */
global REML_x `xvars' /* betas not estimated by ml so pass X as global*/
global REML_nocons `noconstant' /* have to pass as global too */
/* fit comparison fixed-effect (tau2=0) model*/
ml model d0 metareg_ll (`y' `wsvar' = ) /*
*/ if `touse', maximize init(_cons=0) /*
*/ search(off) iterate(0) nowarning nolog
scalar `remll_c' = e(ll) /* log-L, comparison model */
/* estimate tau2 using ml */
local tau2mm = max(`tau2', 1e-4) /* init doesn't work with scalar */
ml model d0 metareg_ll (`y' `wsvar' = ) if `touse',/*
*/ maximize init(_cons=`tau2mm') search(off) nopreserve noscvars /*
*/ `log' tolerance(`tolerance') `mlopts'
if "`e(converged)'" != "1" {
di as error "WARNING: REML estimation of tau2 failed to converge."
di as error "Estimates may be wrong."
di as error "Try adding mm option to use method-of-moments".
}
macro drop REML_x
macro drop REML_nocons
scalar `tau2' = max( _b[_cons], 0)
if `tau2' > 0 {
scalar `remll' = e(ll)
}
else {
scalar `remll' = `remll_c'
}
} /* REML end */
if "`bsest'" == "eb" { /* *** EB start *** */
local oldtau2=-1
local j=0
while abs((`tau2'-`oldtau2')/(`oldtau2'+1e-8)) >= `tolerance' {
local j = `j'+1
tempvar wt ypred wtsq numi
local oldtau2=`tau2'
qui {
gen `wt'=(`wsvar'+`tau2')^-1 if `touse'
regress `y' `xvars' [aw=`wt'] if `touse'
predict `ypred' if `touse'
gen `wtsq'=`wt'^2 if `touse'
gen `numi'=(`wt')*(((e(N)/e(df_r))*((`y'-`ypred')^2))-`wsvar') if `touse'
summ `numi' if `touse', meanonly
local num=r(sum)
summ `wt', meanonly
local tau2=`num'/r(sum)
}
if "`log'" == "log" {
di as txt "Iteration " `j' ": tau^2 = " as res `tau2'
}
}
local tau2 = max(`tau2',0)
} /* EB end*/
/** estimate final model by weighted LS **/
quietly {
gen `v' = `wsvar' + `tau2'
regress `y' `xvars' [iw=1/`v'] if `touse', mse1 `noconstant'
matrix `b' = e(b)
matrix `V' = e(V)
local df_m = e(df_m)
/** knapp and hartung variance adjustment **/
if "`z'" == "" & "`tdist'" == "" {
tempname vkh
predict `resid' if `touse', resid
replace `resid' = `resid'*`resid' / `v' if `touse'
summarize `resid' if `touse', meanonly
local qkh = r(sum) / `df_Q'
matrix `V' = `V' * max(1, `qkh')
}
} /* end quietly */
estimates post `b' `V', depname(`y') obs(`nobs') esample(`touse')
estimates scalar tau2 = `tau2'
estimates scalar df_m = `df_m'
estimates scalar Q = `Q'
estimates scalar df_Q = `df_Q'
estimates scalar I2 = max( ( `Q' - `df_Q' ) / `Q', 0 )
if "`z'" == "" { /* post df_r so get t & F tests not z and chi2 */
estimates scalar df_r = `df_Q'
}
if "`tdist'" =="" & "`z'" == "" {
estimates scalar q_KH = `qkh'
}
if "`wsse'" == "" {
estimates local wsvar "`wsvar'"
}
else {
estimates local wsse "`wsse'"
}
if "`bsest'" == "mm" {
estimates local method "Method of moments"
}
if "`bsest'" == "eb" {
estimates local method "Empirical Bayes"
}
if "`bsest'" == "reml" {
estimates local method "REML"
/* return reml log-l in e(remll) NOT e(ll)
to ensure can't do inappropriate lrtest of fixed effects */
estimates scalar remll = `remll'
if "`remll_c'" != "" {
estimates scalar remll_c = `remll_c'
if (e(remll) < e(remll_c)) | (`tau2' <= 0) {
estimates scalar chi2_c = 0
}
else {
estimates scalar chi2_c = 2*(e(remll)-e(remll_c))
}
}
}
if "`noconstant'" == "" & "`notaucomp'"=="" & "`xvars'" != "" {
estimates scalar tau2_0 = `tau2_0'
}
/* overall F (or chi2) test */
if "`xvars'" != "" {
qui test `xvars'
if "`r(chi2)'" != "" {
estimates scalar chi2 = r(chi2)
}
else {
estimates scalar F = r(F)
}
}
estimates local predict "metareg_p"
estimates local depvar "`y'"
estimates local cmd "metareg"
Display, `level' `eform' `tau2test'
if "`graph'" != "" {
if `: word count `xvars'' != 1 {
di as error in smcl ///
"graph option works only with a single {it:indepvar}"
}
else Graph `y' `xvars' `v' `w' `randomsize'
}
end
program define Graph
version 8.2
args y xvars v w randomsize
tempvar fit
qui predict `fit'
if "`randomsize'" == "" {
local size `w'
}
else {
local size 1/`v'
}
local yti : variable label `y'
if "`yti'" == "" {
local yti `y'
}
scatter `y' `xvars' [aw=`size'], msymbol(oh) ///
|| line `fit' `xvars', sort ///
||, legend(off) ytitle( `yti')
end
program define Display
version 7
syntax [, Level(int $S_level) EForm Tau2test q]
tempname pval i2
if "`eform'" == "eform" {
local eform eform(exp(b))
}
scalar `pval' = chi2tail(e(df_Q), e(Q))
di as txt _n "Meta-regression" /*
*/ _col(55) "Number of obs" _col(70) "= " as res %7.0f e(N)
di as res "`e(method)'" /*
*/ as txt " estimate of between-study variance" /*
*/ _col(55) "tau2" _col(70) "=" as res %8.4g e(tau2)
di as txt "% residual variation due to heterogeneity" /*
*/ _col(55) "I-squared_res" _col(70) "= " as res %6.2f 100 * e(I2) "%"
if "`e(tau2_0)'" != "" {
di as txt "Proportion of between-study variance explained" /*
*/ _col(55) "Adj R-squared " _col(70) "= " _c
di as res %6.2f 100 * ( 1 - e(tau2) / e(tau2_0) ) "%"
}
/* Overall model fit */
if e(df_m) > 1 {
di as txt "Joint test for all covariates" _c
if "`e(df_r)'" == "" {
di as txt _col(55) "Model chi2(" as res e(df_m) as txt ")" /*
*/ _col(70) "= " as res %7.2f e(chi2)
}
else {
di as txt _col(55) "Model F(" as res e(df_m) as txt "," /*
*/ as res e(df_r) as txt ")" _col(70) "= " /*
*/ as res %7.2f e(F)
}
}
di as res "With" _c
if "`e(q_KH)'" == "" {
di as res "out" _c
}
di as txt " Knapp-Hartung modification" _c
if e(df_m) > 1 {
if "`e(df_r)'" == "" {
di as txt _col(55) "Prob > chi2" _col(70) "= " /*
*/ as res %7.4f chi2tail( e(df_m), e(chi2) )
}
else {
di as txt _col(55) "Prob > F" _col(70) "= " /*
*/ as res %7.4f Ftail( e(df_m), e(df_r), e(F) )
}
}
else {
di /* end line */
}
estimates display, level(`level') `eform'
if "`tau2test'" != "" {
di as txt "Test for residual between-study variance (of tau2=0)" /*
*/ _col(55) "Q_res (" as res %1.0f e(df_Q) as txt " df)" /*
*/ _col(70) "= " as res %7.2f e(Q)
di as txt _col(55) "Prob > Q_res" _col(70) "= " as res %7.4f `pval'
if "`e(method)'" == "REML" {
scalar `pval' = chi2tail(1, e(chi2_c))*0.5
if e(chi2_c) <=0 {
scalar `pval'= 1
}
di in smcl as txt "Likelihood-ratio test of tau2=0: " /*
*/ as txt "{help j_chibar:chibar2(01) =}" as res %6.2f e(chi2_c) /*
*/ as txt " Prob > chibar2 = " as res %7.4f `pval'
}
}
end
program define Permute, rclass
version 7
syntax, y(varname numeric) xvars(varlist numeric) wsvar(varname numeric) ///
permute(string) nobs(integer) [noconstant bsest(string) knapphartung z ///
level(passthru) touse(varname numeric)]
gettoken reps 0 : permute, parse(",")
confirm integer number `reps'
if `reps' < 1 {
di as err "permute() must be a positive integer"
exit 198
}
syntax [, Univariable Detail Verbose NOISily Joint(string) * ]
if "`verbose'" != "" { /* verbose is undoc'd synonym for detail */
local detail detail
}
if "`xvars'" == "" {
di as error "permute() option not allowed when no covariates"
exit 198
}
if "`joint'" != "" & "`univariable'" != "" {
di as error "options univariable and joint() cannot both be specified"
exit 198
}
if `:word count `xvars'' == 1 {
local univariable /* ensure unset if only one xvar */
}
if "`univariable'" == "" {
di as txt _n(1) "Monte Carlo permutation test for meta-regression"
}
else {
di as txt _n(1) in smcl /*
*/ "Monte Carlo permutation test for {it:single covariate} meta-regressions"
}
if "`bsest'" == "" {
local bsest "mm" /* mm is default for permutation test */
}
if "`bsest'" == "mm" {
di as res _n "Moment-based " _c
}
else {
di as res _n "REML " _c
}
di as txt "estimate of between-study variance"
if "`knapphartung'" == "" {
local z "z" /* z is default for for permutation test */
di as res "Without " _c
}
else {
di as res "With " _c
}
di as txt "Knapp & Hartung modification to standard errors"
if "`noconstant'" != "" {
di as error "Permutation test inappropriate with no constant"
exit 198
}
local permopts `univariable' `noconstant' `bsest' `knapphartung' `z'
preserve
qui keep if `touse'
foreach x of varlist `xvars' {
local explist "`explist' `x'=r(z_`x')"
local xlist "`xlist' `x'"
}
/* parse varlists in joint() option separated by \ / or | */
local jt `joint'
local nj 0
while "`jt'" != "" {
gettoken tmp jt : jt, parse("\/|")
if strpos("\/|", "`tmp'") {
continue
}
local 0 `tmp'
syntax varlist
local nj = `nj' + 1
local joint`nj' `varlist'
di as txt "joint`nj' : " as res "`joint`nj''"
local explistj "`explistj' joint`nj'=r(chi2`nj')"
local jlist "`jlist' joint`nj'"
}
tempvar n
qui gen `n' = _n if `touse'
tempfile pm pmadj
if "`noisily'" =="" {
local quietly quietly
/* quietly permute then replay (if detail specified)
to suppress full -permute- header */
}
`quietly' permute `n' /*
*/ "metareg_pm `y' `wsvar' `n', xvars(`xvars') joint(`joint') `permopts'" /*
*/ `explist' `explistj', /*
*/ reps(`reps') saving(`pm') replace `options'
tempname R C P B
matrix `R' = r(reps)
matrix `C' = r(c)
matrix `P' = `C' * inv(diag(`R'))
local nx : word count `xvars'
forvalues i = 1/`nx' {
local minreps = min(`reps',`R'[1,`i'])
}
if `minreps' != `reps' {
di as txt "WARNING: some permutations returned missing values" _c
di as txt "See detail below:"
local detail detail
}
/* to get adjusted p-values from -permute-,
replace z-statistics by their largest absolute values
for each permutation */
quietly {
use `pm', clear
tempvar max
gen `max' = 0
foreach v of varlist `xlist' {
replace `max' = abs(`v') if abs(`v') > `max'
}
foreach v of varlist `xlist' {
replace `v' = `max'
}
drop `max'
save `pmadj', replace
permute `xlist' `jlist' using `pmadj', `level'
} // end quietly
matrix `B' = r(b)
matrix `R' = `R' \ r(reps)
matrix `C' = `C' \ r(c)
matrix `P' = `P' \ r(c) * inv(diag(r(reps)))
foreach M in `R' `C' `P' {
matrix rownames `M' = unadj multadj
if "`joint'" != "" {
/* set matrix entries for adjusted joint tests (N/A) to missing */
matrix `M'[2, colnumb(`M',"joint1")] = J(1,`nj',.)
}
}
/* clear results from last permutation so not available to user */
estimates clear
restore
/*** Display results of permutation test ****/
if `nx' == 1 { /* only one xvar */
local sep = sqrt(`P'[1,1]*(1-`P'[1,1])/`reps')
if `sep' == 0 {
local sep .
}
di as txt _n _col(9) "Number of obs =" as res %8.0f _N
di as txt _col(9) "Permutations =" as res %8.0f `reps'
di in smcl as txt "{hline 13}{c TT}{hline 17}"
di in smcl as txt /*
*/ %12s "`y'" " {c |}" _s(1) /*
*/ %6s "p" _s(4) /*
*/ %6s "SE(p)"
di in smcl as txt "{hline 13}{c +}{hline 17}"
di in smcl as txt /*
*/ %12s abbrev(`"`xvars'"',10) /*
*/ " {c |}" _s(2) /*
*/ as result %7.3f `P'[1,1] _s(1) /*
*/ as result %7.4f `sep'
di in smcl as txt "{hline 13}{c BT}{hline 17}"
}
else { /* more than one xvar */
/* Table Head */
di as txt _n "P-values unadjusted and adjusted for multiple testing"
di as txt _n _col(14) "Number of obs =" as res %8.0f `nobs'
di as txt _col(14) "Permutations =" as res %8.0f `reps'
di in smcl as txt "{hline 13}{c TT}{hline 22}"
di in smcl as txt _s(13) "{c |}" _s(12) "P"
di in smcl as txt /*
*/ %12s abbrev("`y'",10) " {c |}" /*
*/ %11s "Unadjusted" %11s "Adjusted"
di in smcl as txt "{hline 13}{c +}{hline 22}"
foreach x of local xvars {
local i = `i' + 1
di in smcl as txt /*
*/ %12s abbrev(`"`x'"',10) /*
*/ " {c |}" _s(4) /*
*/ as result %7.3f `P'[1,`i'] _s(4) /*
*/ %7.3f `P'[2,`i']
}
if "`joint'" != "" {
di in smcl as txt "{hline 13}{c +}{hline 22}"
forvalues j = 1/`nj' {
di in smcl as txt /*
*/ %12s "joint`j'" /*
*/ " {c |}" _s(4) /*
*/ as result %7.3f `P'[1,`nx'+`j']
}
}
/* Table Foot */
di in smcl as txt "{hline 13}{c BT}{hline 22}"
/* largest SE(p) = sqrt( max( p(1-p)/n ) ) */
local maxvarp 0
forvalues i = 1/2 {
forvalues j = 1/`=colsof(`P')'{
local maxvarp = max( `maxvarp', ///
`P'[`i',`j'] * (1 - `P'[`i',`j']) / `R'[`i',`j'] )
}
}
if `maxvarp' == 0 {
local maxvarp .
}
di as txt "largest Monte Carlo SE(P) =" /*
*/ as res %7.4f sqrt(`maxvarp')
}
/* Detailed results if requested, as displayed by -permute- */
if "`detail'" != "" {
di as txt in smcl _n(2) "{title:Unadjusted}"
permute `xlist' `jlist' using `pm', `level'
if `nx' > 1 {
di as txt in smcl _n(2) "{title:Adjusted for multiple testing}"
permute `xlist' using `pmadj', `level'
}
}
di as txt _n "WARNING:"
di as txt "Monte Carlo methods use random numbers, so results may differ between runs."
di as txt "Ensure you specify enough permutations to obtain the desired precision."
return scalar N = `nobs'
return matrix reps = `R'
return matrix c = `C'
return matrix p = `P'
return matrix b = `B'
end
program define metareg_orig
*! v1.06 copyright Stephen Sharp January 1998 STB-42 sbe23
version 5.0
local varlist "req ex min(1)"
local if "opt"
local in "opt"
local options "WSSe(string) WSVar(string) BSest(string) TOLeran(integer 4) Level(integer $S_level)"
local options "`options' NOITer ORIGinal" /* original added by RMH */
parse "`*'"
if "`wsse'"=="" & "`wsvar'"=="" {
di in re "Must specify a variable containing estimate of precision"
di in re "within each trial, using either wsse() or wsvar() option"
exit 198
}
if "`wsse'"~="" & "`wsvar'"~=""{
confirm variable `wsse'
confirm variable `wsvar'
local i=1
while `i'<=_N {
if abs(`wsse[`i']'^2-`wsvar[`i']')>0.00001 {
di in re "Within study variance should be square of within study standard error"
exit 198
}
local i=`i'+1
}
}
if "`wsvar'"~="" {
confirm variable `wsvar'
}
if "`wsse'"~="" {
confirm variable `wsse'
tempvar wsvar
qui gen `wsvar'=`wsse'^2
}
if "`bsest'"=="" {
local bsest "reml"
}
if "`bsest'"~="reml" & "`bsest'"~="ml" & "`bsest'"~="eb" & "`bsest'"~="mm" & "`bsest'"~="" {
di in re "Between study variance estimation method invalid:"
di in re "should be either reml, ml, eb or mm"
exit 198
}
if "`noiter'"~="" & "`bsest'"=="mm" {
di in bl "Warning: mm is a non-iterative method, noiter option ignored"
}
parse "`varlist'", parse(" ")
local y "`1'"
mac shift
local xvars "`*'"
tempvar touse
preserve
qui {
mark `touse' `if' `in'
markout `touse' `y' `xvars'
keep if `touse'
}
qui regress `y' `xvars'
local p=_result(3)
local N=_result(1)
if "`bsest'"=="mm" {
tempvar wt ypred numi one
qui {
gen `wt'=`wsvar'^-1
regress `y' `xvars' [aw=`wt']
predict `ypred'
gen `one'=1
tempname X C Xt C1 XtC1 A A1 A1XtC1 C1X B
mkmat `one' `xvars', matrix(`X')
matrix `C'=J(`N',`N',0)
local i=1
while `i'<=_N {
matrix `C'[`i',`i']=`wsvar'[`i']
local i=`i'+1
}
mat `Xt'=`X''
mat `C1'=inv(`C')
mat `XtC1'=`Xt'*`C1'
mat `A'=`XtC1'*`X'
mat `A1'=inv(`A')
mat `A1XtC1'=`A1'*`XtC1'
mat `C1X'=`C1'*`X'
mat `B'=`C1X'*`A1XtC1'
local trB=trace(`B')
summ `wt'
local denom=_result(18)-`trB'
gen `numi'=`wt'*((`y'-`ypred')^2)
summ `numi'
local num=max(_result(18)-(`N'-(`p'+1)),0)
local newtsq=`num'/`denom'
}
}
if "`bsest'"~="mm" {
local tsq=0.1
local newtsq=0
local j=1
while abs(`tsq'-`newtsq')>=10^(-`toleran') {
tempvar wt ypred wtsq numi
local tsq=`newtsq'
if "`noiter'"=="" {
di in gr "Iteration " `j' ": tau^2 = " in ye `tsq'
}
qui {
gen `wt'=(`wsvar'+`tsq')^-1
regress `y' `xvars' [aw=`wt']
predict `ypred'
gen `wtsq'=`wt'^2
}
if "`bsest'"=="reml" {
qui {
gen `numi'=(`wtsq')*(((`N'/(`N'-(`p'+1)))*((`y'-`ypred')^2))-`wsvar')
summ `numi'
local num=max(_result(18),0)
summ `wtsq'
local denom=_result(18)
local newtsq=`num'/`denom'
}
}
if "`bsest'"=="ml" {
qui {
gen `numi'=(`wtsq')*(((`y'-`ypred')^2)-`wsvar')
summ `numi'
local num=max(_result(18),0)
summ `wtsq'
local denom=_result(18)
local newtsq=`num'/`denom'
}
}
if "`bsest'"=="eb" {
qui {
gen `numi'=(`wt')*(((`N'/(`N'-(`p'+1)))*((`y'-`ypred')^2))-`wsvar')
summ `numi'
local num=max(_result(18),0)
summ `wt'
local denom=_result(18)
local newtsq=`num'/`denom'
}
}
local j=`j'+1
}
}
tempvar wt
qui {
gen `wt'=(`wsvar'+`newtsq')^-1
summ `wt'
}
local sumwt=_result(18)
#delimit ;
di _n
in gr "Meta-analysis regression"
_col(56) "No of studies = " in ye `N' _n
in gr _col(56) "tau^2 method " in ye "`bsest'" _n
in gr _col(56) "tau^2 estimate = " in ye %6.5g `newtsq' _n ;
#delimit cr
if "`bsest'"=="ml" | "`bsest'"=="reml" | "`bsest'"=="eb" {
di in bl "Successive values of tau^2 differ by less than 10^-"`toleran' " :convergence achieved"
}
qui regress `y' `xvars' [aw=`wt']
local scpar=(`sumwt'*(_result(9)^2))/_result(1)
local scpar1=(1/`scpar')
matrix V=get(VCE)
matrix b=get(_b)
matrix v=`scpar1'*V
mat post b v
mat mlout, level(`level')
global S_1 = `N'
global S_2 = `newtsq'
restore
end
exit