def test_dl(self): res = results_meta.exk1_dl eff, var_eff = self.eff, self.var_eff tau2 = _fit_tau_mm(eff, var_eff, 1 / var_eff) assert_allclose(tau2, res.tau2, atol=1e-10) res3 = combine_effects(eff, var_eff, method_re="dl") assert_allclose(res3.tau2, res.tau2, atol=1e-10) assert_allclose(res3.mean_effect_re, res.b, atol=1e-13) assert_allclose(res3.sd_eff_w_re, res.se, atol=1e-10) ci = res3.conf_int(use_t=False) # fe, re, fe_wls, re_wls assert_allclose(ci[1][0], res.ci_lb, atol=1e-10) assert_allclose(ci[1][1], res.ci_ub, atol=1e-10) assert_allclose(res3.q, res.QE, atol=1e-10) # I2 is in percent in metafor assert_allclose(res3.i2, res.I2 / 100, atol=1e-10) assert_allclose(res3.h2, res.H2, atol=1e-10) q, pv, df = res3.test_homogeneity() assert_allclose(pv, res.QEp, atol=1e-10) assert_allclose(q, res.QE, atol=1e-10) assert_allclose(df, 9 - 1, atol=1e-10) # compare FE estimate res_fe = results_meta.exk1_fe assert_allclose(res3.mean_effect_fe, res_fe.b, atol=1e-13) assert_allclose(res3.sd_eff_w_fe, res_fe.se, atol=1e-10) assert_allclose(ci[0][0], res_fe.ci_lb, atol=1e-10) assert_allclose(ci[0][1], res_fe.ci_ub, atol=1e-10) # compare FE, RE with HKSJ adjustment res_dls = results_meta.exk1_dl_hksj res_fes = results_meta.exk1_fe_hksj assert_allclose(res3.mean_effect_re, res_dls.b, atol=1e-13) assert_allclose(res3.mean_effect_fe, res_fes.b, atol=1e-13) assert_allclose(res3.sd_eff_w_fe * np.sqrt(res3.scale_hksj_fe), res_fes.se, atol=1e-10) assert_allclose(res3.sd_eff_w_re * np.sqrt(res3.scale_hksj_re), res_dls.se, atol=1e-10) assert_allclose(np.sqrt(res3.var_hksj_fe), res_fes.se, atol=1e-10) assert_allclose(np.sqrt(res3.var_hksj_re), res_dls.se, atol=1e-10) # metafor uses t distribution for hksj ci = res3.conf_int(use_t=True) # fe, re, fe_wls, re_wls assert_allclose(ci[3][0], res_dls.ci_lb, atol=1e-10) assert_allclose(ci[3][1], res_dls.ci_ub, atol=1e-10) assert_allclose(ci[2][0], res_fes.ci_lb, atol=1e-10) assert_allclose(ci[2][1], res_fes.ci_ub, atol=1e-10) q, pv, df = res3.test_homogeneity() assert_allclose(pv, res_dls.QEp, atol=1e-10) assert_allclose(q, res_dls.QE, atol=1e-10) assert_allclose(df, 9 - 1, atol=1e-10)
def setup_class(cls): cls.res2 = res2 = results_meta.results_or_dl_hk cls.dta = (res2.event_e, res2.n_e, res2.event_c, res2.n_c) eff, var_eff = effectsize_2proportions(*cls.dta, statistic="or") res1 = combine_effects(eff, var_eff, method_re="chi2", use_t=True) cls.eff = eff cls.var_eff = var_eff cls.res1 = res1
def test_pm(self): res = results_meta.exk1_metafor eff, var_eff = self.eff, self.var_eff tau2, converged = _fit_tau_iterative(eff, var_eff, tau2_start=0.1, atol=1e-8) assert_equal(converged, True) assert_allclose(tau2, res.tau2, atol=1e-10) # compare with WLS, PM weights mod_wls = WLS(eff, np.ones(len(eff)), weights=1 / (var_eff + tau2)) res_wls = mod_wls.fit(cov_type="fixed_scale") assert_allclose(res_wls.params, res.b, atol=1e-13) assert_allclose(res_wls.bse, res.se, atol=1e-10) ci_low, ci_upp = res_wls.conf_int()[0] assert_allclose(ci_low, res.ci_lb, atol=1e-10) assert_allclose(ci_upp, res.ci_ub, atol=1e-10) # need stricter atol to match metafor, # I also used higher precision in metafor res3 = combine_effects(eff, var_eff, method_re="pm", atol=1e-7) # TODO: asserts below are copy paste, DRY? assert_allclose(res3.tau2, res.tau2, atol=1e-10) assert_allclose(res3.mean_effect_re, res.b, atol=1e-13) assert_allclose(res3.sd_eff_w_re, res.se, atol=1e-10) ci = res3.conf_int(use_t=False)[1] assert_allclose(ci[0], res.ci_lb, atol=1e-10) assert_allclose(ci[1], res.ci_ub, atol=1e-10) assert_allclose(res3.q, res.QE, atol=1e-10) # the following does not pass yet # assert_allclose(res3.i2, res.I2 / 100, atol=1e-10) # percent in R # assert_allclose(res3.h2, res.H2, atol=1e-10) th = res3.test_homogeneity() q, pv = th df = th.df assert_allclose(pv, res.QEp, atol=1e-10) assert_allclose(q, res.QE, atol=1e-10) assert_allclose(df, 9 - 1, atol=1e-10)
# ### estimate effect size standardized mean difference eff, var_eff = effectsize_smd(mean2, sd2, nobs2, mean1, sd1, nobs1) # ### Using one-step chi2, DerSimonian-Laird estimate for random effects # variance tau # # Method option for random effect `method_re="chi2"` or `method_re="dl"`, # both names are accepted. # This is commonly referred to as the DerSimonian-Laird method, it is # based on a moment estimator based on pearson chi2 from the fixed effects # estimate. res3 = combine_effects(eff, var_eff, method_re="chi2", use_t=True, row_names=rownames) # TODO: we still need better information about conf_int of individual # samples # We don't have enough information in the model for individual confidence # intervals # if those are not based on normal distribution. res3.conf_int_samples(nobs=np.array(nobs1 + nobs2)) print(res3.summary_frame()) res3.cache_ci res3.method_re fig = res3.plot_forest()