* ======================================================================= File: fleiss.SPS Date: 04-APR-2002 Author: Bruce Weaver Notes: Perform meta-analysis as per Fleiss article . * ======================================================================= . * This file implements a general meta-analytic method described by Fleiss. * ----------------------------------------------------------------------- . * Fleiss, JL. The statistical basis of meta-analysis. Statistical Methods * in Medical Research 1993;2:121-145. * ----------------------------------------------------------------------- . * ----------------------------------------- . * Define path for writing temporary files . * ----------------------------------------- . DEFINE !dpath()'C:\'!ENDDEFINE. /* write temp files to C:\ . * Read in data. * N = the number of patients or subjects in each study. * Y = some measure of effect size, VAR.Y its variance. * This example is from Table 3 in the Fleiss article, where Y = ln(RR). DATA LIST LIST / n(f10.0) y var.y(2f8.5) . BEGIN DATA. 1239 .2983 .0320 1529 .3584 .0358 1682 .1896 .0154 626 .1980 .0512 1216 .1998 .0273 4524 -.112 .0077 17187 .0899 .0010 END DATA. numeric study (f3.0). compute study = $casenum. exe. * ----------- Get Fixed Effects Estimate ----------------- . compute w = 1/var.y. /* weight by reciprocal of variance . compute ww = w**2. /* the square of the weight . compute wy = w*y. /* weight times effect size for each study . exe. compute f = 1. exe. aggregate outfile = !dpath + 'f1.sav' /presorted /break = f /* sum over all records */ /npat = sum(n) /* Total number of patients */ /sum.W = sum(w) /sum.WY = sum(wy) /sum.WW = sum(ww). MATCH FILES /FILE=* /FILE= !dpath + 'f1.sav' /RENAME (f = d0) /DROP= d0. EXECUTE. do if missing(sum.w). - compute sum.w = lag(sum.w). - compute sum.wy = lag(sum.wy). - compute sum.ww = lag(sum.ww). end if. exe. numeric z.crit ybar.f se.ybf ll95.f ul95.f ll99.f ul99.f z.f p.f qcomp (f8.3). exe. compute z.95 = 1.96. /* critical Z for 95% CI . compute z.99 = 2.5758. /* critical Z for 99% CI . compute ybar.f = sum.wy/sum.w. /* Point estimate, fixed effects model. compute se.ybf = 1 / sum.w**.5. /* SE of Y-bar (fixed) . compute ll95.f = ybar.f - z.95*se.ybf. compute ul95.f = ybar.f + z.95*se.ybf. compute ll99.f = ybar.f - z.99*se.ybf. compute ul99.f = ybar.f + z.99*se.ybf. compute z.f = ybar.f / se.ybf. compute p.f = 2*(1-(CDF.NORMAL(abs(z.f),0,1))) . compute qcomp = w * (Y - ybar.f)**2. exe. aggregate outfile = !dpath + 'f2.sav' /presorted /break = f /* sum over all records */ /s = n /* s = number of studies */ /q = sum(qcomp). MATCH FILES /FILE=* /FILE= !dpath + 'f2.sav' /RENAME (f = d0) /DROP= d0. EXECUTE. compute p.q = 1 - CDF.CHISQ(q,(s-1)). do if missing(s). - compute s = lag(s). - compute q = lag(q). end if. exe. numeric df (f3.0). compute df = s-1. /* df = number of studies - 1 . exe. * ----------- Now get Random Effects Estimate --------------- . numeric mean.w var.w u d w.star yw.star (f8.3). exe. compute mean.w = sum.w / s. compute var.w = (1/df) * (sum.ww - s * mean.w**2). compute u = df * (mean.w - (var.w/(s * mean.w))). do if (q > df). - compute d = (q - df)/u. else. - compute d = 0. end if. compute w.star = 1 / (d + 1/w). compute yw.star = y*w.star. /* Y * W-star for each study */ exe. aggregate outfile = !dpath + 'f3.sav' /presorted /break = f /* sum over all records */ /num = sum(yw.star) /* numerator of Mean(Y*) */ /sumwstar = sum(w.star). MATCH FILES /FILE=* /FILE= !dpath + 'f3.sav' /RENAME (f = d0) /DROP= d0. EXECUTE. numeric ybar.r se.ybr ll95.r ul95.r ll99.r ul99.r z.r p.r (f8.3). exe. compute ybar.r = num/sumwstar. /* Point estimate, random effects model. compute se.ybr = 1 / sumwstar**.5. /* SE of Y-bar (random) . compute ll95.r = ybar.r - z.95*se.ybr. compute ul95.r = ybar.r + z.95*se.ybr. compute ll99.r = ybar.r - z.99*se.ybr. compute ul99.r = ybar.r + z.99*se.ybr. compute z.r = ybar.r / se.ybr. compute p.r = 2*(1-(CDF.NORMAL(abs(z.r),0,1))) . exe. * ---------- write summary data to files ------------ . * All data on 1st record, so delete all others . select if (study=1). exe. string model (a8). exe. * Save fixed effects estimate . compute model = 'Fixed'. xsave outfile = !dpath + 'fixed.sav' /keep = model s npat ybar.f ll95.f ul95.f z.f p.f q p.q /rename (ybar.f ll95.f ul95.f z.f p.f = y ll95 ul95 z p.z) /compressed. exe. * Save random effects estimate . compute model = 'Random'. xsave outfile = !dpath + 'random.sav' /keep = model s npat ybar.r ll95.r ul95.r z.r p.r /rename (ybar.r ll95.r ul95.r z.r p.r = y ll95 ul95 z p.z) /compressed. exe. get file = !dpath + 'fixed.sav'. ADD FILES /FILE=* /FILE= !dpath + 'random.sav' . EXECUTE. save outfile = !dpath + 'fleiss.sav' /compressed. * Erase temporary files. erase file = !dpath + 'f1.sav'. erase file = !dpath + 'f2.sav'. erase file = !dpath + 'f3.sav'. erase file = !dpath + 'fixed.sav'. erase file = !dpath + 'random.sav'. * ----------------------------------------------------- . * If log-transform was used, convert to original units . * ----------------------------------------------------- . numeric exp.y exp.ll exp.ul (f8.3). compute exp.y = exp(y). compute exp.ll = exp(ll95). compute exp.ul = exp(ul95). exe. format npat (f10.0)/ q (f8.3)/ p.z p.q (f8.4). var lab npat 'Patients' s 'Studies' exp.y 'Exp(Y)' exp.ll 'Lower' exp.ul 'Upper' ll95 'Lower' ul95 'Upper' z 'Z' p.z 'p for Z' q 'Q' p.q 'p for Q'. summarize table = model s npat y ll95 ul95 z p.z q p.q /title = 'Summary Table' /cells = none /format = list nocasenum /stat = none. summarize table = model s npat exp.y exp.ll exp.ul z p.z q p.q /title = 'Summary Table for Exp(Y)' /cells = none /format = list nocasenum /stat = none. * ======================================================================= .