************************************************************************* * CALCULATION OF THE NUMBER NEEDED TO BE EXPOSED (NNE) * * AND THE EXPOSURE IMPACT NUMBER (EIN) * * AND 95% CONFIDENCE INTERVALS * * WITH ADJUSTMENT FOR CONFOUNDING VARIABLES * * * * REFERENCE: BENDER ET AL. (2007), STAT. MED. 26: 5586-5595 * *************************************************************************. *------------------------------------------------------------------* | This is an adaptation for SPSS of the SAS macro written by | | Prof. Dr. Ralf BENDER | | SPSS macro written by Andrew Mackinnon | | | | Questions about the SPSS macro should be directed to | | Andrew.Mackinnon@unimelb.edu.au | | | | Questions about the original procedure and the SAS Macro - | | Prof. Dr. Ralf BENDER Phone: +49 221 35685-451 | | Fax: +49 221 35685-891 | | E-Mail: Ralf@rbsd.de | *------------------------------------------------------------------*. *------------------------------------------------------------------* !! SYNTAX !! !! nne RESP=resp /EXP= /COVAR=covars. !! !! !! !! where !! !! resp specicifies the event of interest (1=yes, 0=no) !! !! exp specifies the binary exposure (1=yes, 0=no) !! !! covars specifies the list of confounders in the model !! !! !! !! INSTRUCTIONS !! !! This is a preconfigured set of instructions for SPSS !! !! Unless you wish to change the function of the program !! !! DO NOT EDIT OR CHANGE THE COMMANDS BETWEEN THE WAVY LINES! !! !! !! !! STEP 1 !! !! Highlight all commands between the wavy lines (DEFINE nne to !! !! !END DEFINE). !! !! Run/execute the selected commands (Ctrl-R) !! !! !! !! STEP 2 !! !! Undertake any necessary recoding of the response and exposure !! !! variables (1=yes/case/exposed; 0=no/noncase/not exposed !! !! !! !! Invoke the macro by name, specifying your variables, e.g., !! !! nne RESP=ill /EXP=riskf /covar= age,sex,covr1,covr4. !! !! !! Select and run the command (Ctrl-R) !! !! !! !! The macro can be rerun as many times as wished in the same !! !! SPSS session simply by issuing the nne command. Step 1 need !! !! not be repeated. A warning message will appear if it is. !! !! !! !! EXAMPLE !! !! The Evans County dataset used in Bender et al (2007) is !! !! available at http://www.sph.emory.edu/~dkleinb/logreg2.htm !! !! With evans.sav as the active dataset, the command !! !! !! !! nne RESP=CHD /EXP=SMK /covar=CAT,AGE,CHL,ECG,HPT,CH,CC. !! !! !! !! should replicate Bender et al.'s results. !! !! NOTES/LIMITATIONS !! !! 1. The macro is run on the active dataset. If you get a lot !! !! of errors, it may be that the dataset you intended to use !! !! is not the current active one. !! !! 2. A maximum of seven covariates can be specified. This is a !! !! limitation of the SPSS GENLIN procedure (as of version 15)!! !! 3. Due to certain idiotosyncrasies of SPSS, covariates must !! !! be specified explicitly and separated by commas. e.g., !! !! CAT,AGE,CHL,ECG will work, CAT AGE TO ECG will not. !! !! 3. Covariates/confounders may be binary or continuous !! !! variables - categorial confounders cannot be specificied !! !! in the current form of the macro. !! !! 4. The output of the GENLIN procedure should be checked to !! !! ensure that it converged and a valid and meaningful !! !! solution has been obtained. !! !! 5. Datasets with system and user-defined missing values may !! !! analysed, but cases with any missing values will be !! !! deleted from all analyses. They are not, however, !! !! removed from the dataset. !! *------------------------------------------------------------------*. *---------------------------------------------------------------------* | Simulation of Cohort Data | *---------------------------------------------------------------------*. INPUT PROGRAM. LOOP #i=1 TO 5000. compute No=#i. compute #alpha=-10. compute #gamma=1.0986123. compute #beta1=0.1823216. compute Z=RV.BINOM(1,0.5). if Z=0 X1=7*RV.NORMAL(0,1)+45. if Z=1 X1=7*RV.NORMAL(0,1)+40. compute prob=exp(#alpha+#gamma*Z+#beta1*X1)/(1+exp(#alpha+#gamma*Z+#beta1*X1)). compute Y=RV.BINOM(1,prob). - END CASE. END LOOP. END FILE. END INPUT PROGRAM. Set mprint=yes. *¤º°`°º¤ø,¸¸,ø¤º°`°º¤ø,¸¸,ø¤º°`°º¤ø,¸¸,ø¤º°`°º¤ø,¸¸,ø¤º°`°º¤ø,¸¸,ø¤º°`°º¤ø. DEFINE NNE (RESP= !charend('/')/ EXP=!charend('/') / COVAR=!charend('/')). PRESERVE. SET MPRINT=NO. SET LENGTH = NONE. * Create temp var for resorting into current case order. COMP ORIG_CASENUM__ = $CASENUM. title 'CALCULATION OF ADJUSTED NNE AND EIN WITH 95% CONF INTERVALS'. *--------------------------------------------------------------------* | Descriptive Analysis | *--------------------------------------------------------------------*. TITLE 'Descriptive Analysis'. DESC !resp !exp !covar /STATISTICS min max mean stddev sum /MISSING=LISTWISE. means !resp !covar BY !exp /CELLS count mean stddev min max sum. *--------------------------------------------------------------------* | Simple 2x2 Table | *--------------------------------------------------------------------*. TITLE 'Simple 2x2 Table with Crude Estimation of OR'. * Temporary selection of non missing cases for consistency with other procedures. TEMPORARY. SELECT IF NMISS(!resp,!exp,!covar)=0. CROSS !exp by !resp /cells COUNT ROW /STATISTICS CHI RISK /METHOD=EXACT TIMER(5). *--------------------------------------------------------------------* | Multiple Logistic Regression Model | *--------------------------------------------------------------------*. title 'Estimation of Adjusted Odds Ratio (Logistic Regression)'. * Output Management Statements to save beta weights and covariance matrix. OMS /SELECT TABLES /IF COMMANDS = ["Generalized Linear Models"] SUBTYPES = ["Covariances of Parameter Estimates"] /DESTINATION FORMAT = SAV NUMBERED = TableNumber_ OUTFILE = "C:~covb.sav.tmp". OMS /SELECT TABLES /IF COMMANDS = ["Generalized Linear Models"] SUBTYPES = ['Parameter Estimates'] /DESTINATION FORMAT = SAV NUMBERED = TableNumber_ OUTFILE = "C:~beta.sav.tmp". GENLIN !resp (REFERENCE=0) WITH !exp !covar /MODEL !exp !covar INTERCEPT=YES DISTRIBUTION=BINOMIAL LINK=LOGIT /MISSING CLASSMISSING=EXCLUDE /PRINT CPS DESCRIPTIVES MODELINFO FIT SUMMARY SOLUTION(EXPONENTIATED) COVB HISTORY (1000). OMSEND. sort cases by !exp. MATRIX. GET xy /FILE=*/VAR=!resp !exp !covar /MISSING = OMIT. GET b /FILE="C:~beta.sav.tmp"/VAR=b. GET covb /FILE="C:~covb.sav.tmp"/VAR= Intercept !exp !covar. * . * xy has response exposure covars . COMP N = nrow(xy). COMP event = csum(xy(:,1)). COMP N_e = csum(xy(:,2)). COMP N_u = N-N_e. COMP K = ncol(xy)-2. * Create beta weights and beta vector. Scale factor (last one) removed. COMP beta0 = b(1). COMP beta1 = b(2). COMP beta2_K = b(3:(K+2)). * Separate unexposed and exposed. COMP E_une = xy(1:N_u,1). COMP E_exp = xy((N_u+1):N,1). COMP covr_une = xy(1:N_u,3:(K+2)). COMP covr_exp = xy((N_u+1):N,3:(K+2)). COMP E_u = csum(E_une). COMP E_e = csum(E_exp). COMP UER = E_u/N_u. COMP EER = E_e/N_e. COMP OddsR = (EER*(1-UER))/(UER*(1-EER)). COMP RD = EER-UER. COMP NNEest = 1/RD. print /title="GENERAL INFORMATION". print {N,event} /title="Sample size and number of events:" /Format="F10.0". print {N_u,E_u;N_e,E_e} /title="Number of unexposed and exposed subjects with events:" /Format="F10.0" /RLABEL "Unexposd" "Exposed " /CLABEL "Total" "Cases". print /title="CRUDE (UNADJUSTED) RESULTS". DO IF RD<0. COMP RD=1/RD. COMP NNEest = 1/NNEest. END IF. PRINT /TITLE="Crude results refer to a harmful effect of exposure" /SPACE 0. PRINT{UER; EER;OddsR;RD} /title="Crude event rates, OR, risk difference: " /Format="F6.4" /RLABEL "Expd ER" "Unxpd ER" "OR" "Risk Dif". DO IF RD=0. PRINT {"Infinity"} /title=" " /SPACE 0 /Format="A8" /RLABEL "NNE ". ELSE. print NNEest /title="Number needed to be exposed (NNE)" /SPACE 0 /Format="F8.2" /RLABEL "NNE". END IF. *---------------------------------------------. PRINT /title=" " /SPACE 0. PRINT /title=" ADJUSTED RESULTS IN TERMS OF NNE" /SPACE 0. PRINT /title= "(AVERAGE RISK DIFFERENCE APPROACH, BASIS: UNEXPOSED PERSONS)" /SPACE 0. PRINT /title=" Note: This method describes the exposure effect for a population" /SPACE 0. PRINT /title=" with a confounder distribution like the unexposed persons." /SPACE 0. COMP LINPRED1 = BETA0 + covr_une*BETA2_k. COMP LINPRED2 = BETA0 + BETA1 + covr_une*BETA2_k. COMP RISK1 = EXP(LINPRED1)/(1+EXP(LINPRED1)). COMP RISK2 = EXP(LINPRED2)/(1+EXP(LINPRED2)). COMP UER = CSUM(RISK1)/N_u. COMP EER = CSUM(RISK2)/N_u. COMP ARD = EER-UER. COMP LOGIST1 = EXP(LINPRED1) / ((1+EXP(LINPRED1))&**2). COMP LOGIST2 = EXP(LINPRED2) / ((1+EXP(LINPRED2))&**2). COMP D1 = CSUM(LOGIST2-LOGIST1)/N_u. COMP D2 = CSUM(LOGIST2)/N_u. * Just defining LOGCOV to be the right size. COMP LOGCOV = COVR_UNE&*0. LOOP J=1 to K. COMP LOGCOV(:,J) = COVR_UNE(:,J)&*(LOGIST2-LOGIST1). END LOOP. COMP D3 = CSUM(LOGCOV)/N_u. COMP D = {D1,D2,D3}. print {UER; EER} /title="Observed unexposed (UER) and hypothetical exposed event rate (EER): " /Format="F6.4" /RLABEL "UER" "EER". DO IF ARD<>0. DO IF ARD>0. PRINT /title= "Adjusted results refer to a harmful effect of exposure". ELSE. COMP ARD = -ARD. PRINT /title= "Adjusted results refer to a beneficial effect of exposure". END IF. COMP NNEest = 1/ARD. COMP VAR_ARD = D*COVB*T(D). COMP SE = SQRT(VAR_ARD). * Specify z values for 95% CIs (because SPSS can't). COMP Zsn = 1.95996398454005. COMP ARD_L = ARD - Zsn*SE. COMP ARD_U = ARD + Zsn*SE. COMP NNE_L = 1/ARD_U. COMP NNE_U = 1/ARD_L. PRINT {ARD;SE;ARD_L;ARD_U} /title= "Average risk differencee (ARD) with SE and 95% CI: " /SPACE 0 /Format="F6.4" /RLABEL "ARD" "SE" "Lo 95%CI" "Up 95%CI". PRINT {NNEest;NNE_L;NNE_U} /title= "Number needed to be exposed (NNE) with 95% CI: " /Format="F6.4" /RLABEL "NNE" "Lo 95%CI" "Up 95%CI". DO IF NNE_U<0 . PRINT /title="Note: A negative upper confidence limit for NNE means that the confidence interval contains 2 areas:". PRINT /title="[lower limit to infinity[ and ]-infinity to upper limit]!" /SPACE 0. END IF. ELSE. ***** THIS IS THE ARD=0 ELSE. PRINT /title="Average risk difference (ARD): 0.0000". PRINT /title="Number needed to be exposed (NNE): Infinity" /SPACE 0. PRINT /title="Sorry, but because ARD=0 the delta method is not applicable". PRINT /title="to calculate the standard error of ARD!" /SPACE 0. END IF. *---------------------------------------------. *---------------------------------------------. PRINT /title=" " /SPACE 0. PRINT /title=" ADJUSTED RESULTS IN TERMS OF EIN" /SPACE 0. PRINT /title= "(AVERAGE RISK DIFFERENCE APPROACH, BASIS: EXPOSED PERSONS)" /SPACE 0. PRINT /title=" Note: This method describes the exposure effect for a population" /SPACE 0. PRINT /title=" with a confounder distribution like the exposed persons." /SPACE 0. COMP LINPRED1 = BETA0 + covr_exp*BETA2_k. COMP LINPRED2 = BETA0 + BETA1 + covr_exp*BETA2_k. COMP RISK1 = EXP(LINPRED1)/(1+EXP(LINPRED1)). COMP RISK2 = EXP(LINPRED2)/(1+EXP(LINPRED2)). COMP UER = CSUM(RISK1)/N_e. COMP EER = CSUM(RISK2)/N_e. COMP ARD = EER-UER. COMP LOGIST1 = EXP(LINPRED1) / ((1+EXP(LINPRED1))&**2). COMP LOGIST2 = EXP(LINPRED2) / ((1+EXP(LINPRED2))&**2). COMP D1 = CSUM(LOGIST2-LOGIST1)/N_e. COMP D2 = CSUM(LOGIST2)/N_e. * Just defining LOGCOV to be the right size. COMP LOGCOV = COVR_exp&*0. LOOP J=1 to K. COMP LOGCOV(:,J) = COVR_EXP(:,J)&*(LOGIST2-LOGIST1). END LOOP. COMP D3 = CSUM(LOGCOV)/N_e. COMP D = {D1,D2,D3}. print {UER; EER} /title="Hypothetical unexposed (UER) and observed exposed event rate (EER): " /Format="F6.4" /RLABEL "UER" "EER". ************** Big if statement here ************. DO IF ARD<>0. DO IF ARD>0. PRINT /title= "Adjusted results refer to a harmful effect of exposure". ELSE. COMP ARD = -ARD. PRINT /title= "Adjusted results refer to a beneficial effect of exposure". END IF. COMP NNEest = 1/ARD. COMP VAR_ARD = D*COVB*T(D). COMP SE = SQRT(VAR_ARD). * Specify z values for 95% CIs (because SPSS can't). COMP Zsn = 1.95996398454005. COMP ARD_L = ARD - Zsn*SE. COMP ARD_U = ARD + Zsn*SE. COMP NNE_L = 1/ARD_U. COMP NNE_U = 1/ARD_L. PRINT {ARD;SE;ARD_L;ARD_U} /title= "Average risk differencee (ARD) with SE and 95% CI: " /SPACE 0 /Format="F6.4" /RLABEL "ARD" "SE" "Lo 95%CI" "Up 95%CI". PRINT {NNEest;NNE_L;NNE_U} /title= "Number needed to be exposed (NNE) with 95% CI: " /Format="F6.4" /RLABEL "NNE" "Lo 95%CI" "Up 95%CI". DO IF NNE_U<0 . PRINT /title="Note: A negative upper confidence limit for NNE means that the confidence interval contains 2 areas:". PRINT /title="[lower limit to infinity[ and ]-infinity to upper limit]!" /SPACE 0. END IF. ELSE. ***** THIS IS THE ARD=0 ELSE. PRINT /title="Average risk difference (ARD): 0.0000". PRINT /title="Number needed to be exposed (NNE): Infinity" /SPACE 0. PRINT /title="Sorry, but because ARD=0 the delta method is not applicable". PRINT /title="to calculate the standard error of ARD!" /SPACE 0. END IF. END MATRIX. * Resort data into original order. SORT CASES BY ORIG_CASENUM__. DELETE VARIABLES ORIG_CASENUM__. * Delete temporary files containing beta weights and var-covar matrix. ERASE FILE = "C:~covb.sav.tmp". ERASE FILE = "C:~beta.sav.tmp". RESTORE. !END DEFINE. *¤º°`°º¤ø,¸¸,ø¤º°`°º¤ø,¸¸,ø¤º°`°º¤ø,¸¸,ø¤º°`°º¤ø,¸¸,ø¤º°`°º¤ø,¸¸,ø¤º°`°º¤ø. nne RESP=CHD /EXP=SMK /covar=CAT,AGE,CHL,ECG,HPT,CH,CC.