/****************************************************************************
* Program/Macro: Figure19_MedianLipidProfile
* Lang/Vers: SAS V9.2
* Author: Robert Gordon / SAS Institute
* Date: 02/23/2012
* Program Title: Figure19_MedianLipidProfile
* Description:
* This code and figure were created based upon code and output created by the
* SAS Institute on the website
*http://support.sas.com/sassamples/graphgallery/Health_and_Life_Sciences.html
* The 'Median of Lipid Profile Overtime' was used as a basis for this figure.
* The code and output for the SAS graphic are available at the above website.
* Edit Log: 23Feb2012 - First version complete
****************************************************************************/
/* Using the import function within SAS, pulled in the CSV Wiki Lab dataset (ADLBC)*/
PROC IMPORT OUT= WORK.adlbc
DATAFILE= "Location/Filename"
DBMS=CSV REPLACE;
GETNAMES=YES;
DATAROW=2;
RUN;
/***************************************************************************************************************************************************************
* SECTION 1 - This code produces the mean profile over time for two *
* treatment* groups (Active and Placebo). * *************************************************************************************************** ***********************************************************/
/* Subset out only the ALT test results for the figure. Create treatment groups. */
data alt;
set adlbc;
if lbtestcd = 'ALT';
if visit ne 'UNSCHEDULED';
if trtp='Placebo' then treat='Placebo';
else treat='Active'; run;
proc sort data=alt;
by treat visitnum; run;
/* Calculate means for each visit, add upper and lower confidence intervals as well as inter-quartile ranges. The current graph uses mean and CIs but could be adapted for median and inter-quartile ranges. Transpose the data and combine to create a merged dataset in the appropriate format to be graphed */
proc means data=alt alpha=0.05 order=data median lclm uclm q1 q3;
class treat visit visitnum;
var lbstresn;
*by trtpcd visit;
output out=mean mean=mean median=median lclm=lclm uclm=uclm; run;
data mean2;
set mean;
keep treat visit visitnum mean lclm uclm;
if treat ne '';
if visit ne '';
if visitnum ne .; run;
proc sort data=mean2;
by visit; run;
data visitnum;
set mean2;
keep visit visitnum;
by visit;
if last.visit then output; run;
proc transpose data=mean2 out=meanfinal;
id treat;
by visit;
var mean; run;
proc transpose data=mean2 out=lower prefix=LCL;
id treat;
by visit;
var lclm; run;
proc transpose data=mean2 out=upper prefix=UCL;
id treat;
by visit;
var uclm; run;
data meanfinal;
set meanfinal;
drop _name_; run;
data lower;
set lower;
drop _name_; run;
data upper;
set upper;
drop _name_; run;
/* This will be the merged dataset, combining the mean, upper and lower confidence intervals for each treatment by visitnum */
data merged;
merge meanfinal lower upper visitnum;
by visit;
if visit='LAB BASELINE' then visitnum=0;
else if visit='WEEK 2' then visitnum=2;
else if visit='WEEK 4' then visitnum=4;
else if visit='WEEK 6' then visitnum=6;
else if visit='WEEK 8' then visitnum=8;
else if visit='WEEK 12' then visitnum=12;
else if visit='WEEK 16' then visitnum=16;
else if visit='WEEK 20' then visitnum=20;
else if visit='WEEK 24' then visitnum=24;
else if visit='WEEK 26' then visitnum=26;
format Active Placebo 4.2; run;
proc sort data=merged;
by visitnum; run;
/* This program creates the number of at risk subjects per treatment and visit. It would be appropriate to simply pull in the number of at risk subjects from a disposition dataset at this step. The data is then added to the merged dataset and ready for graphing */
data atrisk;
input visitnum actrisk placrisk;
datalines;
0 150 150
2 148 149
4 150 144
6 142 136
8 141 136
12 140 128
16 139 134
20 141 136
24 139 138
26 141 139
;
run;
data merged;
merge merged atrisk;
by visitnum;
run;
proc sort data=merged;
by visitnum;
run;
/* Create the template that will be used to graph the merged dataset */
proc template;
define statgraph lipid_profile2;
dynamic title;
begingraph / designwidth=7in designheight=4.5in;
entrytitle title;
layout lattice / columndatarange=union rowweights=(0.85 0.05 0.05 0.05);
layout overlay / cycleattrs=true yaxisopts=(label='Mean (U/L) with 95% CI'
griddisplay=on)
xaxisopts=(offsetmin=0.05 offsetmax=0.05 display=(line ticks
tickvalues)
linearopts=(tickvaluelist=(0 2 4 6 8 10 12 14 16 18 20 22 24 26)));
bandplot x=visitnum limitlower=18 limitupper=20 /display=standard
datatransparency=.7 name=’Normal Range';
scatterplot x=eval(visitnum-0.15) y=Active / yerrorlower=LCLActive
yerrorupper=UCLActive name='Active'
markerattrs=graphdata1(size=9px weight=bold)
errorbarattrs=graphdata1(pattern=solid thickness=1.5);
scatterplot x=eval(visitnum+0.15) y=Placebo / yerrorlower=LCLPlacebo
yerrorupper=UCLPlacebo name='Placebo'
markerattrs=graphdata2(size=9px weight=bold)
errorbarattrs=graphdata2(pattern=solid thickness=1.5);
seriesplot x=eval(visitnum-0.15) y=Active /
lineattrs=graphdata1(pattern=solid thickness=1.5px) name='Active';
seriesplot x=eval(visitnum+0.05) y=Placebo /
lineattrs=graphdata2(pattern=shortdash thickness=1.5px)
name='Placebo';
endlayout;
layout overlay;
entry halign=left 'At risk subjects:';
endlayout;
blockplot x=visitnum block=actrisk / display=(values label)
valuehalign=center label='Active' repeatedvalues=true
valueattrs=graphdata1(size=7.5) labelattrs=graphdata1(size=9
weight=normal);
blockplot x=visitnum block=placrisk / display=(values label)
valuehalign=center label='Placebo' repeatedvalues=true
valueattrs=graphdata2(size=7.5) labelattrs=graphdata2(size=9
weight=normal);
sidebar / spacefill=false;
discretelegend 'Active' 'Placebo' ’Normal Range' / title='Treatment Group
Means: ' titleattrs=(size=8 weight=normal) across=3
valueattrs=(size=8 weight=normal);
endsidebar;
endlayout;
endgraph;
end;
run;
/* Create graph using the template and data. */
ods listing close;
ods html image_dpi=100 file='LipidProfile.html' path='.';
ods graphics / reset noborder width=600px height=400px
imagename='ClinicalHandout_LipidProfile' imagefmt=gif noscale;
proc sgrender data=merged template=lipid_profile2;
dynamic title="Mean of ALT (Alanine Aminotransferase) by Treatment: Profile Over Time";
run;
ods html close;
ods listing;
/***************************************************************************************************************************************************************
* SECTION 2 - This code produces the mean profile over time for three *
* treatment* groups (DrugA, DrugB and Placebo). * ***************************************************************************************************************************************************************/
/* Note that only the assignment of the treatment groups and the template language differ in this section than that in section 1. Therefore, only those sections are depicted. For the code to run correctly, the middle section must be incorporated. */
data alt;
set adlbc;
if lbtestcd = 'ALT';
if visit ne 'UNSCHEDULED';
if trtpn=0 then treat='Placebo';
else if trtpn=1 then treat='DrugA';
else treat = 'DrugB'; run;
proc sort data=alt;
by treat visitnum; run;
/*We now skip to the template language section*/
proc template;
define statgraph lipid_profile2;
dynamic title;
begingraph / designwidth=7in designheight=4.5in;
entrytitle title;
layout lattice/columndatarange=union rowweights=(0.80 0.05 0.05 0.05 0.05);
layout overlay / cycleattrs=true yaxisopts=(label='Mean (U/L) with 95% CI'
griddisplay=on)xaxisopts=(label = 'Week' offsetmin=0.05
offsetmax=0.05 display=(label line ticks tickvalues)
linearopts=(tickvaluelist=(0 2 4 6 8 10 12 14 16 18 20 22 24 26)));
scatterplot x=eval(visitnum-0.20) y=DrugA / yerrorlower=LCLDrugA
yerrorupper=UCLDrugA name='Drug A'
markerattrs=graphdata1(size=9px weight=bold)
errorbarattrs=graphdata1(pattern=solid thickness=1.5);
scatterplot x=eval(visitnum+0.00) y=DrugB / yerrorlower=LCLDrugB
yerrorupper=UCLDrugB name='Drug B'
markerattrs=graphdata2(size=9px weight=bold)
errorbarattrs=graphdata2(pattern=solid thickness=1.5);
scatterplot x=eval(visitnum+0.20) y=Placebo / yerrorlower=LCLPlacebo
yerrorupper=UCLPlacebo name='Placebo'
markerattrs=graphdata2(size=9px weight=bold color=green)
errorbarattrs=graphdata2(pattern=solid thickness=1.5 color=green);
seriesplot x=eval(visitnum-0.20) y=DrugA /
lineattrs=graphdata1(pattern=solid thickness=1.5px) name='Drug A';
seriesplot x=eval(visitnum+0.00) y=DrugB /
lineattrs=graphdata2(pattern=shortdash thickness=1.5px) name='Drug B';
seriesplot x=eval(visitnum+0.20) y=Placebo /
lineattrs=graphdata2(pattern=dash thickness=1.5px color=green)
name='Placebo';
endlayout;
layout overlay;
entry halign=left 'At risk subjects:';
endlayout;
blockplot x=visitnum block=drugarisk / display=(values label)
valuehalign=center label='Drug A' repeatedvalues=true
valueattrs=graphdata1(size=7.5) labelattrs=graphdata1(size=9
weight=normal);
blockplot x=visitnum block=drugbrisk / display=(values label)
valuehalign=center label='Drug B' repeatedvalues=true
valueattrs=graphdata2(size=7.5) labelattrs=graphdata2(size=9
weight=normal);
blockplot x=visitnum block=placrisk / display=(values label)
valuehalign=center label='Placebo' repeatedvalues=true
valueattrs=graphdata2(size=7.5 color=green)
labelattrs=graphdata2(color=green size=9 weight=normal);
sidebar / spacefill=false;
discretelegend 'Drug A' 'Drug B' 'Placebo' / title='Treatment Group: '
titleattrs=(size=8 weight=bold) across=3
valueattrs=(size=8 weight=normal);
endsidebar;
endlayout;
endgraph;
end;
run;
/* Create graph using the template and data. */
ods listing close;
ods html image_dpi=100 file='LipidProfile.html' path='.';
ods graphics / reset noborder width=600px height=400px
imagename='ClinicalHandout_LipidProfile' imagefmt=gif noscale;
proc sgrender data=merged template=lipid_profile2;
dynamic title="Mean of ALT (Alanine Aminotransferase) by Treatment: Profile Over Time";
run;
ods html close;
ods listing;
/***************************************************************************************************************************************************************
* SECTION 3 - This code produces the mean difference from placebo for the 2 *
* active treatment groups (DrugA and DrugB) in section 2. * ***************************************************************************************************************************************************************/
/* This section creates difference between active and placebo at each visit which will be used to create a different graphic that represents the difference. On this plot the confidence intervals (if not including 0) would be significant. */
data altdiff;
input Visit $ DiffA DiffB LA LB UA UB visitnum;
datalines;
Base 0.394 1.633 -2.448 -1.192 3.235 4.457 0
W2 2.875 2.974 -0.456 -0.379 6.206 6.326 2
W4 -1.117 2.647 -4.441 -0.677 2.208 5.972 4
W6 0.025 4.268 -3.114 1.181 3.164 7.346 6
W8 0.911 6.063 -3.229 1.844 5.051 10.283 8
W12 0.471 2.980 -3.430 -0.943 4.371 6.903 12
W16 0.251 2.509 -2.651 -0.512 3.152 5.529 16
W20 0.638 3.519 -2.232 0.680 3.509 6.318 20
W24 0.333 3.107 -5.658 -2.603 6.323 8.807 24
W26 1.822 2.834 -1.590 -0.489 5.234 6.159 26
;
run;
proc sort data=altdiff;
by visitnum; run;
data altdiff;
merge altdiff atrisk;
by visitnum; run;
proc template;
define statgraph lipid_profile3;
dynamic title;
begingraph / designwidth=7in designheight=4.5in;
entrytitle title;
entryfootnote halign=left "* DiffA or DiffB represents the difference in
means between treatment A and placebo or B and placebo,
respectively." /textattrs=(size=8 color=black);
entryfootnote halign=left " Exclusion of 0 in the confidence interval
indicates significance."/textattrs=(size=8 color=black);
layout lattice / columndatarange=union rowweights=(0.80 0.05 0.05 0.05
0.05);
layout overlay / cycleattrs=true yaxisopts=(label='Mean Difference
(U/L)with 95% CI' labelattrs=(size=8) griddisplay=on)
xaxisopts=(offsetmin=0.05 offsetmax=0.05 display=(line ticks
tickvalues)linearopts=(tickvaluelist=(0 2 4 6 8 10 12 14 16 18 20 22 24 26)));
referenceline y=0;
scatterplot x=eval(visitnum-0.20) y=DiffA / yerrorlower=LA yerrorupper=UA
name='Drug A' markerattrs=graphdata1(size=9px weight=bold)
errorbarattrs=graphdata1(pattern=solid thickness=1.5);
scatterplot x=eval(visitnum+0.20) y=DiffB / yerrorlower=LB
yerrorupper=UB name='Drug B'markerattrs=graphdata2(size=9px weight=bold)errorbarattrs=graphdata2(pattern=solid thickness=1.5);
seriesplot x=eval(visitnum-0.20) y=DiffA /
lineattrs=graphdata1(pattern=solid thickness=1.5px) name='Drug A';
seriesplot x=eval(visitnum+0.20) y=DiffB / lineattrs=graphdata2
(pattern=shortdash thickness=1.5px) name='Drug B';
endlayout;
layout overlay;
entry halign=left 'At risk subjects:';
endlayout;
blockplot x=visitnum block=drugarisk / display=(values label)
valuehalign=center label='Drug A' repeatedvalues=true
valueattrs=graphdata1(size=7.5) labelattrs=graphdata1(size=9
weight=normal);
blockplot x=visitnum block=drugbrisk / display=(values label)
valuehalign=center label='Drug B' repeatedvalues=true
valueattrs=graphdata2(size=7.5) labelattrs=graphdata2(size=9
weight=normal);
blockplot x=visitnum block=placrisk / display=(values label)
valuehalign=center label='Placebo' repeatedvalues=true
valueattrs=graphdata2(size=7.5 color=black)
labelattrs=graphdata2(color=black size=9 weight=normal);
sidebar / spacefill=false;
discretelegend 'Drug A' 'Drug B' 'Placebo' / title='*Treatment Group: '
titleattrs=(size=8 weight=bold) across=3
valueattrs=(size=8 weight=normal);
endsidebar;
endlayout;
endgraph;
end;
run;
goptions reset=all;
/* Create graph using the template and data. */
ods listing close;
ods html image_dpi=100 file='LipidProfile.html' path='.';
ods graphics / reset noborder width=600px height=400px
imagename='ClinicalHandout_LipidProfile' imagefmt=jpeg noscale;
*footnote1 j=l h=8pt '* DiffA or DiffB represents the difference in means between treatment A and placebo or B and placebo, respectively. Exclusion of 0
in the confidence interval indicates significance.';
proc sgrender data=altdiff template=lipid_profile3;
dynamic title="Mean Difference of ALT (Alanine Aminotransferase) by Treatment: Profile Over Time";
run;
ods html close;
ods listing;
/**************************************************************************************************************************************************************** SECTION 4 - This code combines sections 2 and 3 by plotting the mean for *
* the three treatment groups (DrugA, DrugB, Placebo)above the mean difference * * between Active and DrugA or Active and DrugB in one graphic. * ***************************************************************************************************************************************************************/
/* This program combines the ‘merged’ dataset from Section 2 and the ‘altdiff’ dataset from Section 3 into the ‘overlay’ dataset. The ‘overlay’ dataset includes both the mean values and the mean difference values */
data overlay;
merge merged altdiff;
by visitnum; run;
proc sort data=overlay;
by visitnum; run;
/* This creates the template which will output the mean graph above the mean
difference graph */
proc template;
define statgraph lipid_profile3;
dynamic title;
begingraph / designwidth=7in designheight=4.5in;
entrytitle title;
entryfootnote halign=left "* Values on the lower plot represents the
difference in means between treatment A and placebo or B and
placebo, respectively. Exclusion of 0 in the confidence interval of the lower plot indicates significance." /textattrs=(size=7 color=black);
layout lattice / columndatarange=union rowweights=(0.35 0.47 0.05 0.05 0.05
0.03);
layout overlay / cycleattrs=true yaxisopts=(label='Mean'
labelattrs=(size=7) tickvalueattrs=(size=8)griddisplay=on)
axisopts=(offsetmin=0.05 offsetmax=0.05 display=(line));
scatterplot x=eval(visitnum-0.20) y=DrugA / yerrorlower=LCLDrugA
yerrorupper=UCLDrugA name='Drug A'
markerattrs=graphdata1(size=9px weight=bold)
errorbarattrs=graphdata1(pattern=solid thickness=1.5);
scatterplot x=eval(visitnum+0.00) y=DrugB / yerrorlower=LCLDrugB
yerrorupper=UCLDrugB name='Drug B'
markerattrs=graphdata2(size=9px weight=bold)
errorbarattrs=graphdata2(pattern=solid thickness=1.5);
scatterplot x=eval(visitnum+0.20) y=Placebo / yerrorlower=LCLPlacebo
yerrorupper=UCLPlacebo name='Placebo'
markerattrs=graphdata2(size=9px weight=bold color=green)
errorbarattrs=graphdata2(pattern=solid thickness=1.5 color=green);
seriesplot x=eval(visitnum-0.20) y=DrugA /
lineattrs=graphdata1(pattern=solid thickness=1.5px) name='Drug A';
seriesplot x=eval(visitnum+0.00) y=DrugB / lineattrs=graphdata2
(pattern=shortdash thickness=1.5px) name='Drug B';
seriesplot x=eval(visitnum+0.20) y=Placebo / lineattrs=graphdata2
(pattern=dash thickness=1.5px color=green) name='Placebo';
endlayout;
layout overlay / cycleattrs=true yaxisopts=(label='Mean Difference'
labelattrs=(size=7) tickvalueattrs=(size=8) griddisplay=on)
xaxisopts=(label='Week' labelattrs=(size=7) tickvalueattrs=(size=7)
offsetmin=0.05 offsetmax=0.05 display=(label line ticks tickvalues)
linearopts=(tickvaluelist=(0 2 4 6 8 10 12 14 16 18 20 22 24 26)));
referenceline y=0;
scatterplot x=eval(visitnum-0.20) y=DiffA / yerrorlower=LA yerrorupper=UA
name='Drug A2' markerattrs=graphdata1(size=7px weight=bold)
errorbarattrs=graphdata1(pattern=solid thickness=1.5);
scatterplot x=eval(visitnum+0.20) y=DiffB / yerrorlower=LB
yerrorupper=UB name='Drug B2' markerattrs=graphdata2(size=9px
weight=bold)errorbarattrs=graphdata2(pattern=solid thickness=1.5);
seriesplot x=eval(visitnum-0.20) y=DiffA /
lineattrs=graphdata1(pattern=solid thickness=1.5px) name='Drug A2';
seriesplot x=eval(visitnum+0.20) y=DiffB /lineattrs=graphdata2
(pattern=shortdash thickness=1.5px) name='Drug B2';
endlayout;
layout overlay;
entry halign=left 'At risk subjects:'/textattrs=(size=7);
endlayout;
blockplot x=visitnum block=drugarisk / display=(values label)
valuehalign=center label='Drug A' repeatedvalues=true
valueattrs=graphdata1(size=7) labelattrs=graphdata1(size=7
weight=normal);
blockplot x=visitnum block=drugbrisk / display=(values label)
valuehalign=center label='Drug B' repeatedvalues=true
valueattrs=graphdata2(size=7) labelattrs=graphdata2(size=7
weight=normal);
blockplot x=visitnum block=placrisk / display=(values label)
valuehalign=center label='Placebo' repeatedvalues=true
valueattrs=graphdata2(size=7 color=green)
labelattrs=graphdata2(color=green size=7 weight=normal);
sidebar / spacefill=false;
discretelegend 'Drug A' 'Drug B' 'Placebo' / title='Treatment Group: '
titleattrs=(size=7 weight=bold) across=3
valueattrs=(size=7 weight=normal);
endsidebar;
endlayout;
endgraph;
end;
run;
goptions reset=all;
/* Create the graph which combines the mean graph with the mean difference graph
using the template and data. */
ods listing close;
ods html image_dpi=100 file='LipidProfile.html' path='.';
ods graphics / reset noborder width=600px height=400px
imagename='ClinicalHandout_LipidProfile' imagefmt=jpeg noscale;
proc sgrender data=overlay template=lipid_profile3;
dynamic title="Mean and Mean Difference (U/L) of ALT (Alanine Aminotransferase) by Treatment: Profile Over Time";
run;
ods html close;
ods listing;