/******************************************************************* Representative Intervention Analysis: Using SSB as our exposure of interest Dataset: fakedata (Note: this is not the real data). Dataset, SAS code, and SAS log file can be downloaded from https://www.dropbox.com/sh/skdazx169j8211d/AAB-1zbWsLTJCh_hp3wW6lFua?dl=0 We run the code on SAS9.4 and no additional macro is required to run these SAS codes. Variable name: Outcomes: BMIZ_ET (BMI Z score at early teen) Time intervals: t t=0: early pregnancy t=1: late pregnancy t=2: 3 years t=3: 4 years t=4: 5 years t=5: 6 years Exposures: Rt_f1 (1 if SSB intake during early pregnancy <= 0.5 servings/day; 0 otherwise) Rt_f2 (1 if SSB intake during late pregnancy <= 0.5 servings/day; 0 otherwise) Rt_3y (1 if SSB intake at 3 years <= 0.5 servings/day; 0 otherwise) Rt_4y (1 if SSB intake at 4 years <= 0.5 servings/day; 0 otherwise) Rt_5y (1 if SSB intake at 5 years <= 0.5 servings/day; 0 otherwise) Rt_6y (1 if SSB intake at 6 years <= 0.5 servings/day; 0 otherwise) Indicator for censoring cen1: 1 if censor at k=0, and 0 otherwise. cen2: 1 if censor at k=1, and 0 otherwise. cen3: 1 if censor at k=2, and 0 otherwise. cen4: 1 if censor at k=3, and 0 otherwise. cen5: 1 if censor at k=4, and 0 otherwise. cen6: 1 if censor at k=5, and 0 otherwise. Baseline covariates L0: gt70k (1 if household income>=70k; 0 otherwise) pabmicat_0 pabmicat_1 pabmicat_2 (paternal BMI <25, 25-29.99, >=30 kg/m2, respectively) bmicat_0 bmicat_1 bmicat_2 (maternal BMI <25, 25-29.99, >=30 kg/m2, respectively) coll_grad (1 if college graduate; 0 otherwise) smoke_3 (1 if smoking during pregnancy; 0 otherwise) white (1 if white/Caucasian; 0 otherwise) Post-baseline covariates L1 : qssb_f1d0 qssb_f1d1 qssb_f1d2 (indicator of tertile variables for ssb during early pregnancy) qcalor_f10 qcalor_f11 qcalor_f12 (indicator of tertile variables for caloric intake during early pregnancy) L2 : qssb_cumavgM0 qssb_cumavgM1 qssb_cumavgM2 (indicator of tertile for average ssb intake during early & late pregnancy) qcalor_cumavgM0 qcalor_cumavgM1 qcalor_cumavgM2 (indicator of tertiles for average ssb intake during early &late pregnancy) qbwz0 qbwz1 qbwz2 (indicator of tertile variables for birth weight Z score) qcalor_ch20 qcalor_ch21 qcalor_ch22 (indicator of tertile variables for caloric intake at 2 years) TV_3ycat_1 (TV watching at age 3, 1 if >=1.6 hours/week ; 0 if <1.6 hours/week L3 : ssb_3ycat_1 (SSB intake at 3 years, 1 if >=1.5 servings/week; 0 if <1.5 servings/week) qssb_cumavgM0 qssb_cumavgM1 qssb_cumavgM2 (indicator of tertile for average ssb intake during early & ate pregnancy) qcalor_cumavgM0 qcalor_cumavgM1 qcalor_cumavgM2 (indicator of tertile for average ssb intake during early &late pregnancy) qbwz0 qbwz1 qbwz2 (indicator of tertile variables for birth weight Z score) qBMIZ_3y0 qBMIZ_3y1 qBMIZ_3y2 (indicator of tertile variables for BMI Z score at age 3 years) qcalor_cumavgC0 qcalor_cumavgC1 qcalor_cumavgC2 (indicator of tertile variables for average caloric intake at age 2 and 3 years) qTV_cumavg_4y0 qTV_cumavg_4y1 qTV_cumavg_4y2 (indicator of tertile variables for average TV watching at age 3 and 4 years) L4: ssb_cumavg_4y_1 (average SSB intake at 3 and 5 years, 1 if >=1.5 servings/week; 0 if <1.5 servings/week) qssb_cumavgM0 qssb_cumavgM1 qssb_cumavgM2 (indicator of tertile for average ssb intake during early & late pregnancy) qcalor_cumavgM0 qcalor_cumavgM1 qcalor_cumavgM2 (indicator of tertile variables for average ssb intake during early amd late preganncy) qbwz0 qbwz1 qbwz2 (indicator of tertile variables for birth weight Z score) qBMIZ_3y0 qBMIZ_3y1 qBMIZ_3y2 (indicator of tertile variables for BMI Z score at age 3 years) qcalor_cumavgC0 qcalor_cumavgC1 qcalor_cumavgC2 (indicator of tertile variables for average caloric intake at age 2 and 3 years) qTV_cumavg_5y0 qTV_cumavg_5y1 qTV_cumavg_5y2 (indicator of tertile variables for average TV watching at age 3,4 and 5 years) L5: ssb_cumavg_5y_0 ssb_cumavg_5y_1 qssb_cumavgM1 qssb_cumavgM2 (indicator of tertile variables for average SSB intake at age 3,4 and 5 years) qssb_cumavgM0 qssb_cumavgM1 qssb_cumavgM2 (indicator of tertile for average ssb intake during early & late pregnancy) qcalor_cumavgM0 qcalor_cumavgM1 qcalor_cumavgM2 (indicator of tertile for average ssb intake during early & late pregnancy) qbwz0 qbwz1 qbwz2 (indicator of tertile variables for birth weight Z score) qBMIZ_3y0 qBMIZ_3y1 qBMIZ_3y2 (indicator of tertile variables for BMI Z score at age 3 years) qcalor_cumavgC0 qcalor_cumavgC1 qcalor_cumavgC2 (indicator of tertile variables for average caloric intake at age 2 and 3 years) qTV_cumavg_6y0 qTV_cumavg_6y1 qTV_cumavg_6y2 (indicator of tertile variables for average TV watching at age 3,4, 5 and 6 years) ***********************SAS codes; starting here**********************************************/ libname gform 'P:\g formula\data'; options notes; options mprint; data fakedata;set gform.fakedata; data data bytimes; set fakedata; if ssb_f1d<=0.5 then Rt_f1=1; else if ssb_f1d ne . then Rt_f1=0; if ssb_f2d<=0.5 then Rt_f2=1; else if ssb_f2d ne . then Rt_f2=0; if ssb_d_3y<=0.5 then Rt_3y=1; else if ssb_d_3y ne . then Rt_3y=0; if ssb_d_4y<=0.5 then Rt_4y=1; else if ssb_d_4y ne . then Rt_4y=0; if ssb_d_5y<=0.5 then Rt_5y=1; else if ssb_d_5y ne . then Rt_5y=0; if ssb_d_6y<=0.5 then Rt_6y=1; else if ssb_d_6y ne . then Rt_6y=0; run; *********************************************************************** Creation of stablized weight, using %macro wtssb ***********************************************************************; %macro wtssb; %*purpose of this macro is to spit out a data set that contains id time and sw, where sw is the stabilized weight; %*treatlist: the variable list for treatment/exposure weight model; %let treatlist0 = ; /*L0*/ %let treatlist1 =qssb_f1d1 qssb_f1d2 qcalor_f11 qcalor_f12; /*L1*/ %let treatlist2 =qssb_cumavgM1 qssb_cumavgM2 qcalor_cumavgM1 qcalor_cumavgM2 qbwz1 qbwz2 qcalor_ch21 qcalor_ch22 TV_3ycat_1; /*L2*/ %let treatlist3 =ssb_3ycat_1 qssb_cumavgM1 qssb_cumavgM2 qcalor_cumavgM1 qcalor_cumavgM2 qbwz1 qbwz2 qBMIZ_3y1 qBMIZ_3y2 qcalor_cumavgC1 qcalor_cumavgC2 qTV_cumavg_4y1 qTV_cumavg_4y2 ; /*L3*/ %let treatlist4 =ssb_cumavg_4y_1 qssb_cumavgM1 qssb_cumavgM2 qcalor_cumavgM1 qcalor_cumavgM2 qbwz1 qbwz2 qBMIZ_3y1 qBMIZ_3y2 qcalor_cumavgC1 qcalor_cumavgC2 qTV_cumavg_5y1 qTV_cumavg_5y2 ; /*L4*/ %let treatlist5 =ssb_cumavg_5y_1 qssb_cumavgM1 qssb_cumavgM2 qcalor_cumavgM1 qcalor_cumavgM2 qbwz1 qbwz2 qBMIZ_3y1 qBMIZ_3y2 qcalor_cumavgC1 qcalor_cumavgC2 qTV_cumavg_6y1 qTV_cumavg_6y2; /*L5*/ %*cenlist: the variable list for censoring weight ; %let cenlist0 = Rt_f1 &treatlist0 ; %let cenlist1 = Rt_f2 &treatlist1 ; %let cenlist2 = Rt_3y &treatlist2 ; %let cenlist3 = Rt_4y &treatlist3 ; %let cenlist4 = Rt_5y &treatlist4 ; %let cenlist5 = Rt_6y &treatlist5 ; proc sort data=bytimesuse; by id ;run; %* Fit numerator of cenoring weight models; proc logistic data=bytimesuse noprint ; model cen1 = &V Rt_f1 ; freq numberhits; output out=cweightn1 p=p_uncen_n1; run; proc logistic data=bytimesuse noprint ; where cen1=0; model cen2 = &V Rt_f2 Rt_f1 ; freq numberhits; output out=cweightn2 p=p_uncen_n2; run; proc logistic data=bytimesuse noprint ; where cen2=0; model cen3 = &V Rt_3y Rt_f2 ; freq numberhits; output out=cweightn3 p=p_uncen_n3; run; proc logistic data=bytimesuse noprint ; where cen3=0; model cen4 = &V Rt_4y Rt_3y ; freq numberhits; output out=cweightn4 p=p_uncen_n4; run; proc logistic data=bytimesuse noprint ; where cen4=0; model cen5 = &V Rt_5y Rt_4y ; freq numberhits; output out=cweightn5 p=p_uncen_n5; run; proc logistic data=bytimesuse noprint ; where cen5=0; model cen6 = &V Rt_6y Rt_5y ; freq numberhits; output out=cweightn6 p=p_uncen_n6; run; *Denominator for cenoring models; proc logistic data=cweightn1 (drop=_level_) noprint; model cen1 = &V &cenlist0 ; freq numberhits; output out=cweight1 p=p_uncen_d1; run; proc logistic data=cweightn2 (drop=_level_) noprint; model cen2 = &V &cenlist1 ; freq numberhits; output out=cweight2 p=p_uncen_d2; run; proc logistic data=cweightn3 (drop=_level_) noprint; model cen3 = &v &cenlist2 ; freq numberhits; output out=cweight3 p=p_uncen_d3; run; proc logistic data=cweightn4 (drop=_level_) noprint; model cen4 = &v &cenlist3 ; freq numberhits; output out=cweight4 p=p_uncen_d4; run; proc logistic data=cweightn5 (drop=_level_) noprint; model cen5 = &v &cenlist4 ; freq numberhits; output out=cweight5 p=p_uncen_d5; run; proc logistic data=cweightn6 (drop=_level_) noprint; model cen6 = &v &cenlist5 ; freq numberhits; output out=cweight6 p=p_uncen_d6; run; *Numerator of treatment/exposure weight; proc logistic descending data=bytimesuse noprint; model Rt_f1= &V ; freq numberhits; output out=tweightn1 p=ptn1; run; proc logistic descending data=bytimesuse noprint; where cen1=0; model Rt_f2= &V Rt_f1 ; freq numberhits; output out=tweightn2 p=ptn2; run; proc logistic descending data=bytimesuse noprint; where cen2=0; model Rt_3y= &V Rt_f2 ; freq numberhits; output out=tweightn3 p=ptn3; run; proc logistic descending data=bytimesuse noprint; where cen3=0; model Rt_4y= &V Rt_3y ; freq numberhits; output out=tweightn4 p=ptn4; run; proc logistic descending data=bytimesuse noprint; where cen4=0; model Rt_5y= &V Rt_4y ; freq numberhits; output out=tweightn5 p=ptn5; run; proc logistic descending data=bytimesuse noprint; where cen5=0; model Rt_6y= &V Rt_5y ; freq numberhits; output out=tweightn6 p=ptn6; run; *denominator of treatment/exposure weight model; proc logistic descending data=tweightn1 (drop=_level_) noprint; model Rt_f1 = &V &treatlist0 ; freq numberhits; output out=tweight1 p=ptd1; run; proc logistic descending data=tweightn2 (drop=_level_) noprint; model Rt_f2 = &V &treatlist1 ; freq numberhits; output out=tweight2 p=ptd2; run; proc logistic descending data=tweightn3 (drop=_level_) noprint; model Rt_3y = &V &treatlist2 ; freq numberhits; output out=tweight3 p=ptd3; run; proc logistic descending data=tweightn4 (drop=_level_) noprint; model Rt_4y = &V &treatlist3 ; freq numberhits; output out=tweight4 p=ptd4; run; proc logistic descending data=tweightn5 (drop=_level_) noprint; model Rt_5y = &V &treatlist4 ; freq numberhits; output out=tweight5 p=ptd5; run; proc logistic descending data=tweightn6 (drop=_level_) noprint; model Rt_6y = &V &treatlist5 ; freq numberhits; output out=tweight6 p=ptd6; run; %*Get stabilized weights; data tweight; merge tweight1 tweight2(keep=id ptd2 ptn2) tweight3(keep=id ptd3 ptn3) tweight4(keep=id ptd4 ptn4) tweight5(keep=id ptd5 ptn5) tweight6(keep=id ptd6 ptn6) ; by id; run; data cweight; merge cweight1(keep=id p_uncen_n1 p_uncen_d1) cweight2(keep=id p_uncen_n2 p_uncen_d2) cweight3(keep=id p_uncen_n3 p_uncen_d3 ) cweight4(keep=id p_uncen_n4 p_uncen_d4) cweight5(keep=id p_uncen_n5 p_uncen_d5) cweight6(keep=id p_uncen_n6 p_uncen_d6); by id; run; proc sort data=tweight; by id ; run; proc sort data=cweight; by id ; run; data weights0; merge tweight cweight; by id ; _sample_ = &bsample; if ptn1 ne . and Rt_f1 = 0 then do; ptn1 = 1 - ptn1; ptd1 = 1 - ptd1; end; if ptn2 ne . and Rt_f2 = 0 then do; ptn2 = 1 - ptn2; ptd2 = 1 - ptd2; end; if ptn3 ne . and Rt_3y = 0 then do; ptn3 = 1 - ptn3; ptd3 = 1 - ptd3; end; if ptn4 ne . and Rt_4y = 0 then do; ptn4 = 1 - ptn4; ptd4 = 1 - ptd4; end; if ptn5 ne . and Rt_5y = 0 then do; ptn5 = 1 - ptn5; ptd5 = 1 - ptd5; end; if ptn6 ne . and Rt_6y = 0 then do; ptn6 = 1 - ptn6; ptd6 = 1 - ptd6; end; cwght_n1 = 1 *p_uncen_n1; cwght_d1 = 1* p_uncen_d1; cwght_n2 = cwght_n1 * p_uncen_n2; cwght_d2 = cwght_d1 * p_uncen_d2; cwght_n3 = cwght_n2 * p_uncen_n3; cwght_d3 = cwght_d2 * p_uncen_d3; cwght_n4 = cwght_n3 * p_uncen_n4; cwght_d4 = cwght_d3 * p_uncen_d4; cwght_n5 = cwght_n4 * p_uncen_n5; cwght_d5 = cwght_d4 * p_uncen_d5; cwght_n6 = cwght_n5 * p_uncen_n6; cwght_d6 = cwght_d5 * p_uncen_d6; twght_n1 = 1 * ptn1; twght_d1 = 1 * ptd1; twght_n2 = twght_n1 * ptn2; twght_d2 = twght_d1 * ptd2; twght_n3 = twght_n2 * ptn3; twght_d3 = twght_d2 * ptd3; twght_n4 = twght_n3 * ptn4; twght_d4 = twght_d3 * ptd4; twght_n5 = twght_n4 * ptn5; twght_d5 = twght_d4 * ptd5; twght_n6 = twght_n5 * ptn6; twght_d6 = twght_d5 * ptd6; stabw=(twght_n6*cwght_n6)/(twght_d6*cwght_d6); run; proc univariate data=weights0 noprint; var stabw ; freq numberhits; output out = pctlweights pctlpre = wgt_ pctlname = llim1 llim2 llim10 ulim90 ulim95 ulim98 ulim99 pctlpts = 1 2 10 90 95 98 99; run; data limits; set pctlweights; _sample_ = &bsample; keep _sample_ wgt_llim1 wgt_llim2 wgt_llim10 wgt_ulim90 wgt_ulim95 wgt_ulim98 wgt_ulim99; run; data weights; merge weights0 limits; by _sample_; run; *we truncated extreme weight to 99th ; data weights; set weights; where cen6=0; if stabw>wgt_ulim99 then stabw=wgt_ulim99; run; /*weight after truncation*/ proc univariate data=weights; var stabw; run; %mend; /***********************************************************************/ /* Weighted Outcome Regression */ /***********************************************************************/ %macro meanssb; %local dimoutc ; %let tmtfunc = Rt_f1 Rt_f2 Rt_3y Rt_4y Rt_5y Rt_6y ; data bytimes5; merge weights bytimesuse; by id ; where cen6=0; array avar &tmtfunc &V; dimoutc=dim(avar); call symput('dimoutc',trim(left(put(dimoutc,8.))) ); run; %*MSM model; proc reg data=bytimes5 outest=outc ; model BMIZ_ET = &tmtfunc &V; freq numberhits; weight stabw; run; data outc2; set outc; if _type_='PARMS'; array avar intercept &tmtfunc &V; array abeta boutc00-boutc&dimoutc; _sample_ = &bsample; do i=1 to dim(avar); abeta(i)=avar(i); end; keep _sample_ boutc00-boutc&dimoutc; run; proc sort data=outc2; by _sample_; run; data bytimes5 ; merge bytimes5 outc2 ; by _sample_; run; %* set rbar function values in MSM under "r_bar=(1,1,1,1,1,1)" ; data intmean ; set bytimes5; array avar uno &tmtfunc &V; array aboutc boutc00-boutc&dimoutc; uno = 1; Rt_6y=1; Rt_5y=1; Rt_4y=1; Rt_3y=1; Rt_f2=1; Rt_f1=1; do i=1 to dim(aboutc); meanbmi=sum(meanbmi,aboutc(i)*avar(i)); end; keep id _sample_ numberhits &V &tmtfunc meanbmi ; run; proc means data = intmean noprint ; var meanbmi ; freq numberhits; output out = intmeanm mean = meanbmifinal ; run; %* set rbar function values in MSM under "r_bar=(0,0,0,0,0,0)" ; data intmean0 ; set bytimes5; array avar uno &tmtfunc &V; array aboutc boutc00-boutc&dimoutc; uno = 1; Rt_6y=0; Rt_5y=0; Rt_4y=0; Rt_3y=0; Rt_f2=0; Rt_f1=0; do i=1 to dim(aboutc); meanbmi=sum(meanbmi,aboutc(i)*avar(i)); end; keep id _sample_ numberhits &V &tmtfunc meanbmi ; run; proc means data = intmean0 noprint ; var meanbmi ; freq numberhits; output out = intmeanm0 mean = meanbmifinal0 ; run; %mend; *********************************************************************** Get 95% confidence Intervals by boostraps ***********************************************************************; %macro ipw_mean(weights=,V=,nsamples=,samplesize=,resultsdata=,samplestart=, sampleend=); %*create data set with number of hits for each individual id for bootstrap; data _idholders_ (index = (bsample)); do bsample = 0 to &nsamples ; do _newid_ = 1 to &samplesize; output ; end; end; run; proc surveyselect data= _idholders_ method = urs n= &samplesize seed = 1232 out = _idsamples (keep = bsample _newid_ numberhits ) outall ; strata bsample ; run; data _idsamples ; set _idsamples ; if bsample = 0 then numberhits = 1 ; run; %*add sequential newid to bytimes data set; proc sort data=bytimes nodupkey out=indiv; by id; run; data indiv (keep= _newid_ id); set indiv; _newid_ =_n_; run; proc sort data=indiv; by id;run; proc sort data=bytimes; by id; data bytimes; merge indiv bytimes; by id; run; %*bootstrap loop starts here - for now just have this; %do bsample = &samplestart %to &sampleend; %put bootstrap sample &bsample; proc sort data=bytimes; by _newid_; data bytimesuse ; merge bytimes _idsamples (keep = _newid_ numberhits bsample where = (bsample = %eval(&bsample))); by _newid_ ; drop bsample ; run; %&weights; %meanssb; proc sort data=intmeanm; by _type_; /*r bar=(1,1,1,1,1,1)*/ proc sort data=intmeanm0; by _type_; /*r bar=(0,0,0,0,0,0)*/ data results; merge intmeanm intmeanm0 ; by _type_; meanbmidiff=meanbmifinal-meanbmifinal0; _sample_ = &bsample; keep _sample_ meanbmifinal meanbmifinal0 meanbmidiff ; run; %if &bsample=&samplestart %then %do; data resultsall; set results; run; %end; %else %do; proc append base = resultsall data = results; run; %end; %end; /*bootstrap loop*/ proc print data=resultsall; title '&bsample'; run; data &resultsdata; set resultsall; run; %mend; %*Call to ipw_mean macro to ultimately create permanent data sets with all results needed for paper ; *********************************************************************** Get Final IPW estimate(%ipw_mean) For bootstrapp of 100, user can specify sampling from 0 to 100 (samplestart=0, sampleend=100) ***********************************************************************; *output (when setting samplestart=0 and sampleend=0, will get estimate without 95%CI; *%ipw_mean(weights=wtssb,V=gt70k pabmicat_1 pabmicat_2 bmicat_1 bmicat_2 coll_grad smoke_3 white, nsamples=1000, samplesize=1584, resultsdata=ssbmain_0,samplestart=0,sampleend=0); *output; *Obs meanbmifinal meanbmifinal0 meanbmidiff _sample_ ; *1 0.34214 -0.18031 0.52245 0 ; *let run bootstrap with 50 samples as an example; %ipw_mean(weights=wtssb,V=gt70k pabmicat_1 pabmicat_2 bmicat_1 bmicat_2 coll_grad smoke_3 white, nsamples=1000, samplesize=1584, resultsdata=ssbmain_0,samplestart=0,sampleend=50); data estimates; set ssbmain_0; int=0; /*just for merging */ if _sample_ = 0; run; data bs; set ssbmain_0; if _sample_ > 0; run; /*SW*/ proc univariate data=bs noprint; var meanbmidiff meanbmifinal meanbmifinal0 ; output out = pctlci pctlpre = meanbmidiff_ meanbmifinal_ meanbmifinal0_ pctlname = lower upper pctlpts = 2.5 97.5 ; histogram ; run; data pctlci; set pctlci; int=0; proc sort data=pctlci; by int; proc sort data=estimates; by int; data pctlci2 ; merge pctlci estimates; by int; run; title '&intdata diff bs SW results'; proc print data=pctlci2; var meanbmifinal meanbmifinal_lower meanbmifinal_upper /*had everyone consumed below 1, and 95%CI*/ meanbmifinal0 meanbmifinal0_lower meanbmifinal0_upper /*had everyone consumed above 1, and 95%CI*/ meanbmidiff meanbmidiff_lower meanbmidiff_upper /*difference, and 95%CI*/ ; run; /* Obs meanbmifinal meanbmifinal_lower meanbmifinal_upper meanbmifinal0 meanbmifinal0_lower meanbmifinal0_upper meanbmidiff meanbmidiff_lower meanbmidiff_upper 1 0.34214 0.22794 0.45828 -0.18031 -1.00189 0.54877 0.52245 -0.27018 1.31865 In this fake example, r_bar=1 0.34 (0.23, 0.46) r_bar=0 -0.18 (-1.00, 0.55) diff 0.52 (-0.27, 1.32) */