/* study-specific data */ data chor; length Study $ 50; length Country $ 50; input study $ e n Country; datalines; Fehr_2011 305 4094386 Australia Bienvenu_2006 251 4337627 France Sarajlija_2015 102 857142 Serbia Wong_2007 7 123968 China Magnússon_2001 0 41896 Iceland Strømme_2000 1 14542 Norway Isaksen_2012 3 15662 Norway Aguilera_2007 1 63675 Spain Chakrabarti_2005 1 13202 UK Fombonne_2003 2 5227 UK ; run; /* calculating binomial CIs for individual proportions */ data chor; set chor; Prev = (e/n)*100000; if e=0 then LCL = 0; else LCL = (e/(e+(1+n-e)*FINV(0.975,2*(1+n-e),2*e)))*100000; if e = n then UCL = 100000; else UCL=((e+1)*FINV(0.975,2*(e+1),2*(n-e))/(n-e+(e+1)*FINV(0.975,2*(e+1),2*(n-e))))*100000; run; /* proc sort data=chor out=chor; by Country; run; */ /* random effects meta-analysis based on glimmix */ ods output ParameterEstimates=Outputs_glimmix Covtests=Covtests_glimmix; proc glimmix data=chor; class study; model e/n = / solution link=logit dist=binomial; random intercept / subject=study; covtest 'var(study) = 0' 0 .; run; data Outputs_glimmix2 (keep=Prev LCL UCL); set Outputs_glimmix; Prev = exp(Estimate) / (1 + exp(Estimate)) * 100000; LCL = exp(Estimate-1.96*StdErr) / (1 + exp(Estimate-1.96*StdErr)) * 100000; UCL = exp(Estimate+1.96*StdErr) / (1 + exp(Estimate+1.96*StdErr)) * 100000; run; /* calculating total event counts and sample size */ ods output Summary=Totals; proc means data=chor sum; var e n; run; data totals (keep=Study e n); set totals; Study='All (Random Effects)'; e=e_Sum; n=n_Sum; run; data glimmix3; merge totals Outputs_glimmix2; run; /* merging study-specific estimates with the random effects meta-analysis */ data all; set glimmix3 chor; if Study = 'All (Random Effects)' then C=1; else C=2; run; data all2; set chor glimmix3; if Study = 'All (Random Effects)' then C=1; else C=2; run; /* calculating the I_squared statistic */ data chor; set chor; count = _N_; run; ods output Summary=Count; proc means data=chor max; var count; run; /* calculating the number of studies */ data I_squared; merge covtests_glimmix count; Q_df = (count_Max-1); /* df for the Q statistic = number of studies - 1 */ Q = cinv(1-ProbChiSq, Q_df); /* Q statistic computed from the heterogeneity p-value and Q_df */ I_squared = (Q - Q_df)/Q; /* I squared */ run; /* Generating a Funnel Plot */ data funnel_plot; set chor; LOGIT = LOG(((e+0.5)/n)/(1-(e+0.5)/n)); SE_LOGIT = 1/(e+0.5) + 1/(n-(e+0.5)); Margin = (UCL-LCL)/2; run; /* 0.5 is a continuity correction */ title "Funnel Plot - logits"; proc sgplot data=funnel_plot; scatter y=SE_LOGIT x=LOGIT / MARKERATTRS=size (size=1 cm); xaxis label="LOGIT" /*min=-1 max=1*/; yaxis label="STANDARD ERROR"; goptions symbol dev=jpeg300 xpixels=1500 ypixels=1500; run; data funnel_plot; set funnel_plot; Y = LOGIT / SE_LOGIT; X = (1 / SE_LOGIT); run; proc genmod data=funnel_plot; model y = x / dist=normal link=identity; run; /* Funnel Plot - Proportions */ ods html; title "Funnel Plot - Proportions"; proc sgplot data=funnel_plot; scatter y=Margin x=Prev / MARKERATTRS=size (size=1 cm); xaxis label="PREVALENCE" /*min=-1 max=1*/; yaxis label="MARGIN OF ERROR"; goptions symbol dev=jpeg300 xpixels=1500 ypixels=1500; run; /* Forest plot */ ods graphics / attrpriority=none; title 'Meta-analysis summary (Forest Plot)'; proc sgplot data=all noautolegend; styleattrs datasymbols=(diamondfilled circlefilled); scatter x=Prev y=Study / group=C grouporder=ascending xerrorlower=LCL xerrorupper=UCL; refline 7.5 / axis=x; xaxis label="Prevalence per 100,000 females with 95% Confidence Intervals " min=0 max=60; yaxis label="Studies"; goptions dev=jpeg300 xmax=3.25 ymax=3.25 xpixels=1500 ypixels=1500; run; /* Tabular Summary */ data all2; set all2; Order = _N_; run; proc sort data=all2 out=all3; by descending C descending Order; run; title 'Meta-analysis summary (Table format)'; proc print data=all3; format Prev LCL UCL 4.1; run; title 'glimmix heterogeneity test'; proc print data = I_squared; var Q Q_df ProbChiSq I_squared; run;