/*********************************************************************************************/ /* */ /* FILENAME: mainverse.sas */ /* DEVELOPERS: Jim Weir & Stephen Senn (University of Glasgow) */ /* Version 1.0 */ /* Date: August 29, 2008 */ /* History of the revision: */ /* Datasets MH_OR, MH_RR and Peto_OR can be run by inverse and random macros */ /* Prefix ma for all meta analysis macros. Thus inverse.sas is now mainverse.sas (1Jul08) */ /* Add option in setting alpha level for confidence interval with 0.05 as default (8Jul08) */ /* Revision on marandom and magalbraith (1Aug08) */ /* Revision maqq and marandom for qq plot generated by random (7Aug08) */ /* Revision for mabinary to correct 'error' for calls using method=mh_or and method=all */ /* (20Aug08) */ /* Revision for maforest to correct reference line for mh_lor, mh_rr and peto_lor and */ /* marandom to set negative variance to zero for HT profile likelihood (29Aug08) */ /* Revision (16Sep2008 - S.Modin) removed goptions reset=all so that code will work for */ /* batch submit in unix and user can have control over graphics */ /* SAS VERSION: 8.2 */ /* Input dataset should contain: */ /* */ /* study - study name (or number) !NOTE! that study names are limited to 8 characters. */ /* ES - Effect Size */ /* se - standard error */ /* sampsize - sample size !NOTE! this is optional and does not need to be entered. */ /* */ /* When running the macro, all that has to be entered is the data set name and whether or */ /* not the sample sizes are available. If you wish to use a value other than 0.05 for */ /* confidence interval calculations then a value for alpha can be entered when calling the */ /* macro. Example: %mainverse(dataset=recovery,alpha=0.1,sampsize=yes) */ /* */ /* If you have a column in the dataset with the sample size for each study then you should */ /* enter 'YES' into the macro for 'sampsize'. Otherwise 'NO' should be entered. */ /* */ /* If you have run any of the Mantel-Haenszel or Peto methods, it is possible to enter a */ /* data set produced by that method. These data sets contain the effect size, standard */ /* error and sample size for each study. The names of the data sets that can be entered */ /* into this fixed effects inverse variance macro are listed below: */ /* */ /* mh_or2 - contains mantel haenszel odds ratio and standard error */ /* mh_lor2 - contains mantel haenszel log odds ratio and standard error */ /* mh_rr2 - contains mantel haenszel relative risk and standard error */ /* mh_lrr2 - contains mantel haenszel log relative risk and standard error */ /* mh_rd2 - contains mantel haenszel risk difference and standard error */ /* peto_or2 - contains peto odds ratio and standard error */ /* peto_lor2 - contains peto log odds ratio and standard error */ /* */ /* Note that the standard errors in the mh_or2, mh_rr2 and pero_or2 data sets were */ /* calculated in the binary macro using the delta rule. */ /* */ /*********************************************************************************************/ %macro mainverse(dataset= ,alpha=0.05,sampsize= ); goptions reset=all; proc iml; use &dataset; /* Read in each of the three variables */ read all var {study} into study; read all var {ES} into ES; read all var {se} into se; /* If the sample size has been entered, then read it in */ %if %upcase(&sampsize) = YES %then %do; read all var {sampsize} into sampsize; sample_size = sum(sampsize); %end; /* Calculate confidence intervals for each of the studies */ lower = ES - ((probit(1-(&alpha/2)))#se); upper = ES + ((probit(1-(&alpha/2)))#se); /* Calculate the weight attached to each study. */ /* This is equal to the reciprocal of the variance. */ w = 1/(se##2); /* Calculate the combined effect size, combined standard error, confidence interval, */ /* Z (with p-value), Q (with p-value), degrees of freedom and I squared value using the */ /* formulae listed in the documentation. */ Comb_ES = (sum(w#ES))/(sum(w)); Comb_se = sqrt(1/sum(w)); low_lim = Comb_ES-((probit(1-(&alpha/2)))*Comb_se); upp_lim = Comb_ES+((probit(1-(&alpha/2)))*Comb_se); Z = (Comb_ES/Comb_se); zpval = 2*(1-probnorm(abs(Z))); Q = sum(w#(ES##2)) - ((sum(w#ES))##2/sum(w)); df = (nrow(ES)-1); qpval = 1-cdf('chisquare',Q,df); I_I = 100#((Q-df)/Q); /* If I-squared is negative then set it to zero */ if I_I < 0 then do; I_I = 0; end; /* Display the above results in the output window */ print "Fixed Effects Analysis: Inverse Variance"; print "Using the '&dataset' data set"; print Comb_ES [label="Estimate"]; print Comb_se [label="s.e"]; print low_lim [label="Wald Lower"] upp_lim [label="Wald Upper"]; print Z [label="Z"]; print zpval [label="Z p-value"]; print Q [label="Q"]; print qpval [label="Q p-value"]; print df [label="df"]; print I_I [label="I-squared"]; /* If the sample sizes have been entered then print the sum */ %if %upcase(&sampsize) = YES %then %do; print sample_size [label="Sample Size"]; %end; /* If the input data set is taken from the binary macro and */ /* contains log values i.e mh_lor2, mh_lrr2, peto_lor2 then */ /* take the exponential of the results and display them. */ %if %upcase(&dataset = mh_lor2) | %upcase(&dataset = mh_lrr2) | %upcase(&dataset = peto_lor2) %then %do; CombES = exp(Comb_ES); lowlim = exp(low_lim); upplim = exp(upp_lim); print " "; print "The input data set from the binary macro contained log values."; print "Below is the back-transformed estimate and confidence interval from the results."; print CombES [label="Estimate"]; print lowlim [label="Wald Lower"] upplim [label="Wald Upper"]; %end; /***************************/ /* CREATE OUTPUT DATA SETS */ /***************************/ /* Aim is to generate three output datasets that can be used for plotting purposes: */ /* inv_var will contain data for each study and also show the combined results. */ /* inv_var2 will only contain data for each study. */ /* inv_var3 will only contain the combined results. This data set will be deleted */ /* at the end of the program as it has no further use. */ /************/ /* inv_var2 */ /************/ /* First make a data set with study, effect size, standard error and confidence */ /* limits for each of the studies. */ /* If the sample sizes have been entered then add them to the data set. */ %if %upcase(&sampsize) = YES %then %do; create inv_var2 var {study ES se lower upper sampsize}; append; %end; %else %do; create inv_var2 var {study ES se lower upper}; append; %end; /************/ /* inv_var3 */ /************/ /* Set the combined estimate results to have the same variable names as those in */ /* the data set 'inv_var2'. This allows the combined results to be added into the */ /* same table as the data in 'inv_var2'. */ study = 'INV_VAR'; ES = Comb_ES; se = Comb_se; lower = low_lim; upper = upp_lim; /* Create a data set called 'inv_var3' that contains the combined results. */ /* If the sample sizes have been entered then add the sum of these to the data set. */ %if %upcase(&sampsize) = YES %then %do; sampsize = sample_size; create inv_var3 var {study ES se lower upper sampsize}; append; %end; %else %do; create inv_var3 var {study ES se lower upper}; append; %end; /***********/ /* inv_var */ /***********/ /* Merge 'inv_var2' and 'inv_var3' together to create an output data set called 'inv_var'. */ /* Also add a new variable called 'Type' that displays the type of estimate. */ /* i.e 'Single' or 'Combined'. */ data inv_var; set inv_var2 inv_var3; if study= 'INV_VAR' then TYPE= 'Combined'; else TYPE= 'Single'; run; /*******************************/ /* Remove unwanted data set */ /* inv_var3 has no further use */ /*******************************/ proc datasets lib=work nolist; delete inv_var3; run; quit; quit; %mend mainverse;