1. Alice M. Cheng, Chiltern International Ltd
Justina M. Flavin, SimulStat Inc.
2. Objectives
To explore both traditional and the latest
approaches to ensure Legend Consistency
(or Line Attribute Consistency).
3. History of this paper
Is the Legend in your SAS/Graph® Output
Telling the Right Story?
Justina M. Flavin, Art Carpenter
(SUGI 29 Paper, Emphasis on Using GPLOT Procedure)
Is the Legend in your SAS/Graph® Output
STILL Telling the Right Story?
Alice Cheng, Justina M. Flavin
(Emphasis on Using SGPLOT Procedure)
(First Edition, WUSS 2011)
(Some Discussions on Attribute Map and SGPANEL Procedure)
(Second Edition, PharmaSUG 2012)
(Emphasis on Attribute Map; Only Mentioned SGPANEL)
(Third Edition, WUSS 2012)
(More Emphasis on Attribute Map and an Example of SGPANEL)
3
4. AGENDA
The Nature of SGPLOT Procedure.
How are Line Attributes (color, symbol and
style) Assigned?
Line Attributes Inconsistency Problem.
5 Solutions to Resolve Line Inconsistency Issues.
Additional Comments on Attribute Maps.
Line Attributes in the SGPANEL Procedure.
4
4
5. INTRODUCTION
Line Attributes (line color, symbol and style).
Placebo
Drug A
Drug B
Drug C
It is critical that line attributes are CONSISTENT.
5
5
6. THE NATURE OF SGPLOT
HOW ARE LINES ATTRIBUTES (COLOR, SYMBOL
and STYLE) ASSIGNED?
6
6
7. Treatment
Order is
based
on Input Data
Order in
PROC
SGPLOT.
Figure 1A: Average Scores of 4 Treatments Over Time
7
7
8. INPUT DATASET
data DRUG;
input TRT & $7. MONTH : 2. SCORE : 3. @@;
label TRT=„Treatment:‟
MONTH=„Month‟
SCORE=„Average Score‟;
Datalines;
Placebo 1 10 Placebo 2 15 Placebo 3 18 Placebo 4 20 Placebo 5 22 Placebo 6 24
Drug A 1 30 Drug A 2 40 Drug A 3 60 Drug A 4 85 Drug A 5 93 Drug A 6 100
Drug B 1 20 Drug B 2 30 Drug B 3 45 Drug B 4 70 Drug B 5 90 Drug B 6 90
Drug C 1 25 Drug C 2 30 Drug C 3 35 Drug C 4 55 Drug C 5 70 Drug C 6 80
;
run;
Note: Based on input dataset DRUG,
Order of Treatments is: Placebo, Drug A, Drug B, Drug C.
8
8
9. DEFINE STYLE
proc template;
define style STYLES.MYSTYLES;
Type ODSTEMPLATE in the command
parent= STYLES.DEFAULT ; line of SAS Windowing Environment
to find the definition of
STYLES.DEFAULT.
*--- Re-define Style for Line Attributes. ---*;
*--- Line Attributes for kth Treatment. ---*;
style GraphDatak from GraphDatak /
linestyle = enter line style number for the kth treatment
contrastcolor = enter color for the kth treatment
markersymbol=„enter color for the kth treatment’;
… more codes …
end;
run;
9
9
10. DEFINE STYLE
SAS Version Default Style Comments
9.2 Default All other styles are
the children of
Default styles.
9.3 HTMLBlue New SAS 9.3M2 color
styles, such as PEARL
and SAPPHIRE, are the
children of HTMLBlue
Style.
11. DEFINE STYLE
proc template;
define style STYLES.MYSTYLES;
parent=STYLES.DEFAULT;
*--- Re-define Style for Line Attributes. ---*;
style GraphData1 from GraphData1 / linestyle=1 contrastcolor=red
markersymbol=„circle’; * Line Attributes for 1st Treatment. ;
style GraphData2 from GraphData2 / linestyle=2 contrastcolor=blue
markersymbol=„square‟; * Line Attributes for 2nd Treatment. ;
style GraphData3 from GraphData3 / linestyle=3 contrastcolor=green
markersymbol=„diamond‟; * Line Attributes for 3rd Treatment. ;
style GraphData4 from GraphData4 / linestyle=4 contrastcolor=orange
markersymbol=„circlefilled‟; * Line Attributes for 4th Treatment. ;
*--- Re-define other styles to make sure the graph is easier to read. ---*;
class GraphFonts / „GraphLabelFont‟=(“Arial”, 18pt, bold)
„GraphValueFont‟=(“Arial”, 15pt, bold)
„GraphTitleFont‟=(“Arial”, 25pt, bold);
style graphbackground from graphbackground / color = _undef_;
end; run;
Note: The k-th treatment in the input dataset takes on the k-th color here.
For instance, the first treatment (Placebo) takes on the RED color.
11
10
12. USE SGPLOT TO GENERATE FIGURE
ods listing style=STYLES.MYSTYLE;
title „Score Over Time by Treatment‟;
proc sgplot data=DRUG;
series y=SCORE x=MONTH / group=TRT markers;
keylegend / noborder title=„Treatment‟;
run;
Use the style STYLES.MYSTYLE.
Assign TRT as the GROUP variable.
12
13. PROC SGPLOT VS PROC GPLOT
SGPLOT GPLOT
Default Order Data Order Internal
of Group Value
(TRT) Variable
Line Style Statement in Symboln
Attributes PROC TEMPLATE Statement
So if you want to present the values based on Internal Value of the Group
Variable in PROC SGPLOT (as in GPLOT), prior to SAS v9.3, you have to
sort by the Group (TRT) variable.
13
14. Or in SAS Version 9.3, use …
proc SGPLOT data = DRUG;
series y=SCORE x=MONTH / GROUP=TRT
GROUPORDER=ascending
markers;
run;
GROUP=variable and GROUPORDER=ascending/descending/data options
in the SERIES statement specify:
the order of the values in the GROUP variable
based on which the line attributes have been assigned to the groups.
14
15. Now based on
the ascending
order of the
value of TRT.
Figure 1B: With GROUP=TRT and GROUPORDER=ASCENDING, the order of
the treatments in the legend and the line attributes have been changed.
15
15
17. LINE ATTRIBUTES
Line Attributes (line color, symbol and style).
Drug A
Drug B
Drug C
Placebo
It is critical that line attributes are CONSISTENT.
17
17
18. WHAT IF DRUG B IS NO LONGER IN A STUDY?
SGPLOT
Drop Drug B We Want
(Default)
Drug A
Drug B
Drug C
Placebo
THE LINE ATTRIBUTES ARE NO LONGER CONSISTENT.
18
18
19. Inconsistency!!!
Inconsistency
In line attribute.
Drug C should
GREEN and
Placebo should
be ORANGE!
Figure 2: The same line inconsistency issues in the GPLOT procedure now
re-appears in the output for SGPLOT procedure when Drug B is excluded.
19
20. THE FIGURE WE WANT …
Average
Note: The lines in the legend are consistent with the lines when
all 4 treatments are available.
20
20
21. 5 SOLUTIONS TO RESOLVE
LEGEND INCONSISTENCY ISSUES
21
21
23. Solution # 1. Use Dummy Data
data DUMMY;
length TRT $7.; u Create a Dummy
TRT=„Drug A‟; MONTH= . ; SCORE= . ; output;
Dataset for all
TRT=„Drug B‟; MONTH= . ; SCORE= . ; output;
TRT=„Drug C‟; MONTH= . ; SCORE =. ; output;
Treatment groups.
TRT=„Placebo‟; MONTH= . ; SCORE =.; output;
run;
data DRUG_WT_DUMMY; v Append DRUG data at
set DUMMY the end of DUMMY data
DRUG (where=(TRT ne „Drug B‟) );
to retain the correct
run;
Treatment group order.
*- Generate Figure 3A. -*;
ods listing style=STYLES.MYSTYLE;
proc sgplot data=DRUG_WT_DUMMY; w
series y=SCORE x=MONTH / group=TRT markers; Use DRUG_WT_DUMMY
keylegend / noborder title=„Treatment‟; run; to create Figure 3A.
23
23
24. Solution # 1. Use Dummy Data
Since Drug B
is not supposed
to be in this
figure.
Drug B should
NOT be in the
legend!!!
Figure 3A: The Add Dummy Data Approach ensures line consistency,
However, the excluded treatment group Drug B remains in the legend.
24
24
26. Solution # 2. Re-Map Line Attributes
Create a LOOKUP dataset with data for every possible
GROUP variable value and its line attributes.
From LOOKUP dataset, get GROUP variable values
and the corresponding line attributes based on current
source database.
Create a new template by
re-defining the Style GraphDatan statements.
Apply the newly defined Style to PROC SGPLOT.
26
26
27. Solution # 2. RE-MAP LINE ATTRIBUTE
*- u Establish a LOOKUP dictionary for line attribute for each drug. -*;
data LOOKUP;
input ID & $7. LINESTYLE : 3. COLOR : $6. SYMBOL : $12.;
cards;
Drug A 1 red circle
Drug B 2 blue square
Drug C 3 green diamond
Placebo 4 orange circlefilled
;
run;
27
27
28. Solution # 2. RE-MAP LINE ATTRIBUTE
%*- v Define LINEATTR macro to create Style Template with line attributes. -*;
%macro lineattr ( indata = /* Enter Input Data Set Name */
, lookup=LOOKUP /* Enter LOOKUP Dataset */
, idvar=ID /* ID variable in LOOKUP Data Set. */
, groupvar=TRT /* Enter Group Variable. */
, style=STYLES.MYSTYLE2 /* Enter Style name to be output. */
, parent_style=STYLES.MYSTYLE /* Enter Parent Style. */
)/ des=„To create line attributes in Style Template‟;
%local I;
%*- w Get line attribute for treatment groups from LOOKUP. -%;
%*- Note: only line attributes for treatment groups in the dataset specified in -*%;
%*- the dataset specified in &indata will be kept. -*%;
proc sql noprint;
create table LINEATTR as
select distinct L.*, D.&GROUPVAR
from &indata D
left join
&LOOKUP
on D.&GROUPVAR=L.&IDVAR
order by D.&GROUPVAR; quit;
28
28
29. Solution # 2. RE-MAP LINE ATTRIBUTE
%*-x Assign value for the line style, colors and symbol of each treatment. -*%;
data null;
set LINEATTR;
call symput („LINESTYLE‟ || strip(_n_, 3.)), LINESTYLE);
call symput („COLOR‟ || strip ( put (_n_, 3.)), COLOR);
call symput („SYMBOL‟|| strip(put (_n_, 3.)), strip(SYMBOL) ); run;
%*- y Redefine your line attributes in a new style. -*%;
proc template;
define style &STYLE;
parent=&parent_style;
%do i=1 %to &sqlobs;
style GraphData&i from GraphData&i / linestyle=&&LINESTYLE&i
contrastcolor=&&color&I markersymbol=&&symbol&i;
%end;
end;
run;
%mend lineattr;
29
29
30. Solution # 2. RE-MAP LINE ATTRIBUTE
*-z Create a dataset based on DRUG, excluding TRT B. -*;
data DRUG_noB;
set DRUG (where=(TRT ne „Drug B‟));
run;
*- { Invoke %lineattr to create STYLES.MYSTYLES2 with the correct line styles. -*;
%lineattr(indata=DRUG_noB,
style=STYLES.MYSTYLES2);
*- | Apply STYLES.MYSTYLES to create graph. -*;
ods listing style=STYLES.MYSTYLES2;
Title h=20pt „Score Over Time by Treatment‟;
proc sgplot data=DRUG_noB;
series y=SCORE x=MONTH / group=TRT markers;
keylegend / noborder title=„Treatment: „;
run;
30
30
31. Average
This is the
figure we
want!
Figure 3B: 3 remaining treatments are represented by lines consistent in appearance as
those seen in Figure 1B. Legend reflects only the lines in the figure.
31
31
32. SOLUTION # 3
RE-CODE INTERNAL VALUES
OF GROUP VARIABLE
32
32
33. WHAT IF DRUG B IS NO LONGER IN A STUDY?
SGPLOT
Drop Drug B We Want
(Default)
Drug A
Drug B
Drug C
Placebo
NOTE: Line attributes before the deleted group, namely DRUG A,
remain intact.
33
33
34. WHAT IF PLACEBO IS NOT IN A STUDY?
SGPLOT
Drop Placebo We Want (Default)
Drug A
Drug B
Drug C
Placebo
NOTE: Line attributes are consistent.
Line attributes before the deleted group remain intact.
34
34
35. Solution # 3. RE-CODE INTERNAL VALUES OF GROUP VARIABLE
So if one knows ahead of the treatments that are going to be
dropped, one can put these treatments to be dropped last,
in terms of its internal value.
The line attributes for the remaining treatment groups will
remain intact.
35
35
36. Solution # 3. RE-CODE INTERNAL VALUES OF GROUP VARIABLE
*- u Define formats for re-coding group variable, TRT. -*;
proc format;
invalue INTRTF „Drug A‟ = 1
„Drug B‟ = 4 Note that Drug B is now
„Drug C‟= 2 assigned to the largest value!
„Placebo‟=3;
value TRTF 1= „Drug A‟
2=„Drug C‟ Recode the internal values to
3=„Placebo‟ associate with new treatment
4=„Drug B‟; assignment.
run;
36
36
37. Solution # 3. RE-CODE INTERNAL VALUES OF GROUP VARIABLE
*-v Re-coded the value from TRT to TRT2 so that treatment groups to -*;
*- be dropped have higher internal values and will be listed last. -*;
data DRUG_RECODED;
set DRUG (where=(TRT ne „Drug b‟) ); Resign new internal numeric
TRT2=input(TRT, intrf.); values to TRT2.
label TRT2=„Treatment: „;
format TRT2 TRTF.; Format new internal numeric
run; values to have character
appearances.
*- Sort the data based on the internal value of the re-coded variable -*;
*- of TRT2. -*;
proc sort data=DRUG_RECODED;
by TRT2;
run;
37
37
38. Solution # 3. RE-CODE INTERNAL VALUES OF GROUP VARIABLE
*- w Re-order the line attributes to match internal values of group
variable, TRT2 -*;
proc template;
define style STYLES.MYSTYLE3;
parent=STYLES.MYSTYLE;
style GraphData1 from GraphData1 / linestyle=1 contrastcolor=RED
markersymbol=„circle‟;
style GraphData2 from GraphData2 / linestyle=3 contrastcolor=GREEN
markersymbol=„diamond‟;
style GraphData3 from GraphData3 / linestyle=4 contrastcolor=ORANGE
markersymbol=„circlefilled‟;
style GraphData4 from GraphData4 / linestyle=2 contrastcolor=BLUE
markersymbol=„square‟;
end;
run;
Note: line attributes for Drug B
is now the last in the list.
38
38
39. Solution # 3. RE-CODE INTERNAL VALUES OF GROUP VARIABLE
*- w Re-order the line attributes to match internal values of group
variable, TRT2 -*;
Create a new style.
proc template;
define style STYLES.MYSTYLE3;
parent=STYLES.MYSTYLE;
style GraphData1 from GraphData1 / linestyle=1 contrastcolor=RED
markersymbol=„circle‟;
style GraphData2 from GraphData2 / linestyle=3 contrastcolor=GREEN
markersymbol=„diamond‟;
style GraphData3 from GraphData3 / linestyle=4 contrastcolor=ORANGE
markersymbol=„circlefilled‟;
style GraphData4 from GraphData4 / linestyle=2 contrastcolor=BLUE
markersymbol=„square‟;
end;
run;
39
39
40. Solution # 3. RE-CODE INTERNAL VALUES OF GROUP VARIABLE
*- x Generate Figure 3B that excludes Drug B with Re-coded
variable, TRT2 -*; Use a new style here!
ods listing style=STYLES.MYSTYLE3;
title „Score Over Time by Treatment‟;
proc sgplot data=DRUG_RECORDED;
series y=SCORE x=MONTH / group=TRT2 markers;
keylegend/noborder title=„Treatment: „;
run;
Use recoded variable TRT2,
Instead of TRT.
40
40
41. Average
This is the
figure we
want!
Figure 3B: 3 remaining treatments are represented by lines consistent in appearance
as those seen in Figure 1B. Legend reflects only the lines in the figure.
41
41
42. SOLUTION # 4
USE INDEX= OPTION IN
x
GRAPH TEMPLATE LANGUAGE (GTL)
42
42
43. PROC SGPLOT vs Graph Template Language (GTL)
PROC SGPLOT GTL
Single Cell Plot Multiple Cell Plot
Quality Graphics Higher Quality Graphics
Some Customization More Customization
Quick and Easy to Require Significant Time
Learn and Use and Effort to Learn
43
43
44. Use of INDEX= Option in GTL to Ensure Line Consistency.
(Only Available Using GTL.)
What if you have yet to master GTL?
If you have SAS 9.3, you can use SG Attribute Map (Solution #5).
If not and if you only need a simple plot that can be produced by the SG
procedure, you can use TMPLOUT options to get the code to create the
template and then render that template.
44
44
45. Use of INDEX= Option in GTL to Ensure Line Consistency.
Example:
proc sgplot data=DRUG
tmplout=“c:wuss_2012line_plot.sas”;
series y=SCORE x=MONTH / group=TRT markers;
keylegend/noborder title=„Treatment: „;
run;
45
45
46. Solution # 4. USING INDEX= Option IN GTL
*- u Create a variable IDVAL to associate the group variables with -*;
*- line attributes defined in STYLES.MYSTYLE. -*;
data DRUG_IDVAL;
set DRUG (where=(TRT NE „Drug B‟) );
if TRT=„Drug A‟ then IDVAL=1;
else if TRT=„Drug B‟ then IDVAL=2;
else if TRT=„Drug C‟ then IDVAL= 3; Create IDVAL variable.
else if TRT=„Placebo‟ then IDVAL=4;
run;
46
46
47. Solution # 4. USING INDEX=Options IN GTL
*- u Create a variable IDVAL to associate the group variables with -*;
*- line attributes defined in STYLES.MYSTYLE. -*;
data DRUG_IDVAL;
set DRUG (where=(TRT NE „Drug B‟) );
if TRT=„Drug A‟ then IDVAL=1;
else if TRT=„Drug B‟ then IDVAL=2;
else if TRT=„Drug C‟ then IDVAL= 3; Create IDVAL variable.
else if TRT=„Placebo‟ then IDVAL=4;
run;
proc template;
define style STYLES.MYSTYLE; STYLES.MYSTYLE
parent=STYLES.DEFAULT;
style GraphData1 from GraphData1 / linestyle=1 contrastcolor=RED
markersymbol=‘circle’;
style GraphData2 from GraphData2 / linestyle=2 contrastcolor=BLUE
markersymbol=‘square’;
style GraphData3 from GraphData3 / linestyle=3 contrastcolor=GREEN
markersymbol=‘diamond’;
style GraphData4 from GraphData4 / linestyle=4 contrastcolor=ORANGE
markersymbol=‘circlefilled’; end; run;
47
47
48. Solution # 4. USING INDEX IN GTL
*- u Create a variable IDVAL to associate the group variables with -*;
*- line attributes defined in STYLES.MYSTYLE. -*;
data DRUG_IDVAL;
set DRUG (where=(TRT NE „Drug B‟) );
if TRT=„Drug A‟ then IDVAL=1;
else if TRT=„Drug B‟ then IDVAL=2;
else if TRT=„Drug C‟ then IDVAL= 3; Create IDVAL variable.
else if TRT=„Placebo‟ then IDVAL=4;
run;
proc template;
define style STYLES.MYSTYLE; STYLES.MYSTYLE
parent=STYLES.DEFAULT;
style GraphData1 from GraphData1 / linestyle=1 contrastcolor=RED
markersymbol=‘circle’;
style GraphData2 from GraphData2 / linestyle=2 contrastcolor=BLUE
markersymbol=‘square’;
style GraphData3 from GraphData3 / linestyle=3 contrastcolor=GREEN
markersymbol=‘diamond’;
style GraphData4 from GraphData4 / linestyle=4 contrastcolor=ORANGE
markersymbol=‘circlefilled’;
end; run;
48
48
49. Solution # 4. USING INDEX= OPTION IN GTL
*- u Create a variable IDVAL to associate the group variables with -*;
*- line attributes defined in STYLES.MYSTYLE. -*;
data DRUG_IDVAL;
set DRUG (where=(TRT NE „Drug B‟) );
if TRT=„Drug A‟ then IDVAL=1;
else if TRT=„Drug B‟ then IDVAL=2;
Create IDVAL variable.
else if TRT=„Drug C‟ then IDVAL= 3;
else if TRT=„Placebo‟ then IDVAL=4;
run;
*- v Template SGPLOT was obtained from TMPLOUT options in PROC SGPLOT.-*;
*- INDEX options in SERIESPLOT statement has been added manually. -*;
proc template;
define statgraph SGPLOT; Define new template SGPLOT.
begingraph;
EntryTitle “Average Score Over Time by Treatment‟/ textattrs=(size=2pct);
layout overlay;
seriesplot x=MONTH y=SCORE /
primary=true group=TRT index=IDVAL display=(markers)
LegendLabel=“Average Score” Name=“SERIES”;
DiscreteLegend “Series” / Location=Outside Title=“Treatment: “ Border=false;
endlayout; 49
endgraph; Add Manually.
49 run;
end;
49
50. Solution # 4. USING INDEX= OPTION IN GTL
*- w Use PROC SGRENDER to render the graph from the stored graphics -*;
* Template SGPLOT. -*;
ods listing style=STYLES.MYSTYLE; Specify STYLES.MYSTYLE.
proc sgrender data=DRUG_IDVAL template=SGPLOT;
run;
Use dataset with IDVAL. Use template SGPLOT we just created.
50
50
51. Average
This is the
figure we
want!
Figure 3B: 3 remaining treatments are represented by lines consistent in appearance
as those seen in Figure 1B. Legend reflects only the lines in the figure.
51
51
52. SOLUTION # 5
USE OF ATTRIBUTE MAP
(Available in SAS Version 9.3)
52
52
53. SOLUTION # 5: Use of Attribute Map
5A. Using SG Attribute Map Approach
(i.e., with Statistical Graphics Procedures)
5B. Using Attribute Map with GTL Approach
53
54. SOLUTION # 5A
USE OF SG ATTRIBUTE MAP
(Available in SAS Version 9.3)
54
54
55. Solution # 5A. Using SG Attribute Map Approach
*- u Create Attribute Map Data Set named MYATTRMAP. -*;
data MYATTRMAP;
retain ID “MYID”;
input VALUE & $7. LINESTYLE : 3. LINECOLOR : $6
MARKERSYMBOL : $12 MARKCOLOR : $6.;
cards;
Drug A 1 red circle red
Drug B 2 blue square blue
Drug C 3 green diamond green
Placebo 4 orange circlefilled orange
; run;
*- v Reference to MYATTRMAP to define the line attributes. -*;
ods listing;
title „Average Score Over Time by Treatment‟;
proc sgplot data=DRUG dattrmap=MYATTRMAP;
series y=SCORE x=MONTH / group=TRT attrid=MYID
marker;
keylegend / noborder title=“Treatment: “; run;
55
55
56. Average
This is the
figure we
want!
Figure 3B: 3 remaining treatments are represented by lines consistent in appearance as
those seen in Figure 1B. Legend reflects only the lines in the figure.
56
56
57. SOLUTION # 5B
USE OF ATTRIBUTE MAP
WITH GTL APPROACH
(Available in SAS Version 9.3)
57
57
58. Basic Graph Template Language (GTL)
Structure
proc template;
define statgraph template-name;
begingraph / < designheight=h > <designwidth=w> <options>;
layout type of layout;
… statements …
endlayout;
endgraph;
end;
run;
59. Solution # 5B. Using Attribute Map with GTL Approach
*- u Define a template named SGPLOT with Discrete Attribute Map Data set. -*;
proc template;
define statgraph SGPLOT;
BeginGraph;
Entrytitle “Average Score Over Time by Treatment”/textattrs=(size=2 pct);
*- v Define the attribute map and assign the name “lineattr”. -*;
DiscreteAttrMap name=“lineattr” / ignore=true;
value “Drug A” / lineattrs=(pattern=1 color=RED) markerattrs=(color=RED symbol=circle);
value “Drug B” / lineattrs=(pattern=2 color=BLUE) markerattrs=(color=BLUE symbol =square);
value “Drug C” / lineattrs=(pattern=3 color=GREEN) markerattrs=(color=GREEN symbol =diamond);
value “Placebo” / lineattrs=(pattern=4 color=ORANGE) markerattrs=(color=ORANGE symbol
=circlefilled);
EndDiscreteAttrMap;
*- w Associate the attribute map with input data column ID and -*;
*- assign the name GROUPMARKERS to named association. -*;
DiscreteAttrVar attrvar=groupmarkers var=TRT attrmap=“lineattr” ;
59
59
60. Solution # 5B. Using Attribute Map with GTL Approach
*- u Define a template named SGPLOT with Discrete Attribute Map Data set. -*;
proc template;
define statgraph SGPLOT;
BeginGraph;
Entrytitle “Average Score Over Time by Treatment”/textattrs=(size=2 pct);
Case-Sensitive!Case-Sensitive!
Must Match! Must Match!
*- v Define the attribute map and assign the name “lineattr”. -*;
DiscreteAttrMap name=“lineattr” / ignore=true;
value “Drug A” / lineattrs=(pattern=1 color=RED) markerattrs=(color=RED symbol=circle);
value “Drug B” / lineattrs=(pattern=2 color=BLUE) markerattrs=(color=BLUE symbol =square);
value “Drug C” / lineattrs=(pattern=3 color=GREEN) markerattrs=(color=GREEN symbol =diamond);
value “Placebo” / lineattrs=(pattern=4 color=ORANGE) markerattrs=(color=ORANGE symbol
=circlefilled);
EndDiscreteAttrMap;
*- w Associate the attribute map with input data column ID and -*;
*- assign the name GROUPMARKERS to named association. -*;
DiscreteAttrVar attrvar=groupmarkers var=TRT attrmap=“lineattr” ;
60
60
61. Solution # 5B. Using Attribute Map with GTL Approach
*- u Define a template named SGPLOT with Discrete Attribute Map Data set. -*;
proc template;
define statgraph SGPLOT;
BeginGraph;
Entrytitle “Average Score Over Time by Treatment”/textattrs=(size=2 pct);
*- v Define the attribute map and assign the name “lineattr”. -*;
DiscreteAttrMap name=“lineattr” / ignore=true;
value “Drug A” / lineattrs=(pattern=1 color=RED) markerattrs=(color=RED symbol=circle);
value “Drug B” / lineattrs=(pattern=2 color=BLUE) markerattrs=(color=BLUE symbol =square);
value “Drug C” / lineattrs=(pattern=3 color=GREEN) markerattrs=(color=GREEN symbol =diamond);
value “Placebo” / lineattrs=(pattern=4 color=ORANGE) markerattrs=(color=ORANGE symbol
=circlefilled);
EndDiscreteAttrMap; Case-Sensitive! Values in quotes must
match with the internal value of TRT!
*- w Associate the attribute map with input data column ID and -*;
*- assign the name GROUPMARKERS to named association. -*;
DiscreteAttrVar attrvar=groupmarkers var=TRT attrmap=“lineattr” ;
61
61
62. Solution # 5B. Using Attribute Map with GTL
Approach (Continued)
*- x Define the Series Plot. -*;
Layout overlay;
seriesplot x=MONTH y=AVG_SCORE/ primary=true group=groupmarkers
display=(markers)
Legendlabel=“Average Score” Name=“SERIES” ;
DiscreteLegend “SERIES” / Location=Outside border=false Title=“Treatment: “;
EndLayout;
EndGraph;
End; run;
*- y Use PROC SGRENDER to render the graph from stored graphics template SGPLOT.-*;
ods listing;
proc sgrender data=DRUG template=SGPLOT;
where TRT ne “Drug B”; run;
62
62
63. Solution # 5B. Using Attribute Map with GTL Approach (Continued)
Case-Sensitive! Must Match!
*- x Define the Series Plot. -*;
Layout overlay;
seriesplot x=MONTH y=AVG_SCORE/ primary=true group=groupmarkers
display=(markers)
Legendlabel=“Average Score” Name=“SERIES” ;
DiscreteLegend “SERIES” / Location=Outside border=false Title=“Treatment: “;
EndLayout;
EndGraph;
End; run;
*- yUse PROC SGRENDER to render the graph from stored graphics template SGPLOT.-*;
ods listing;
proc sgrender data=DRUG template=SGPLOT;
where TRT ne “Drug B”; run;
63
63
64. Average
This is the
figure we
want!
Figure 3B: 3 remaining treatments are represented by lines consistent in appearance
as those seen in Figure 1B. Legend reflects only the lines in the figure.
64
64
65. Which of the 5 approaches should be applied?
A Quick Peek Only?
YES NO
Use Method 1: Have SAS v9.3?
Dummy Data
YES NO
Need Custom Graph? Use Method 4:
INDEX Option in GTL
YES NO
Use Method 5B: Use Method 5A:
Attribute Map SG Attribute Map
in GTL
65
66. Which of the 5 approaches should be applied?
Not Recommended because
Method 2:
it does not take advantage of
Re-map Line Attributes
SAS new easier to use feature.
Not Recommended because
Method 3:
(1). it does not take advantage of
Re-code Internal Values
SAS new easier to use feature.
of GROUP variable
(2). May not know which treatment
will be dropped in the future.
66
67. Which of the 5 approaches should be applied?
Not Recommended because
Method 2:
it does not take advantage of
Re-map Line Attributes
SAS new easier to use feature.
Not Recommended because
Method 3:
(1). it does not take advantage of
Re-code Internal Values
SAS new easier to use feature.
of GROUP variable
(2). May not know which treatment
will be dropped in the future.
67
69. Attribute Map
Discrete Range
Attribute Map Attribute Map
Using SG Using Using
Procedures GTL GTL
69
70. Attribute Map
Discrete Range
Attribute Map P Attribute Map
Using SG Using Using
Procedures GTL GTL
P= Already Discussed.
P P
70
71. Discrete To display discrete value.
Attribute Map Example: Treatment Groups
71
72. Discrete To display discrete value.
Attribute Map Example: Treatment Groups
To display value based on the
Range range that value belongs to.
Attribute Map Example: Body Mass Index
(BMI)
72
73. Consider the following SCORE dataset:
USUBJID TRT BBMI VISIT SCORE
100 Placebo 29.8 1 8
100 Placebo 29.8 2 12
100 Placebo 29.8 3 16
100 Placebo 29.8 4 18
100 Placebo 29.8 5 19
100 Placebo 29.8 6 21
200 Placebo 27.6 1 12
200 Placebo 27.6 2 18
200 Placebo 27.6 3 16
200 Placebo 27.6 4 14
200 Placebo 27.6 5 17
200 Placebo 27.6 6 13
… more data …
BBMI = Body Mass Index at Baseline (kg/m2)
73
74. 4 Categories based on BMI:
BMI at Baseline Category
(kg/m2)
< 19 Underweight
19 - < 26 Normal
26 - < 30 Overweight
>= 30 Obese
74
75. 4 Categories
based on BMI
at baseline are
reflected in the
Spectrum.
Note: Color of the dots represents the Baseline BMI value of individual
subject at the corresponding month.
75
76. Using Range Attribute Map with GTL Approach
*- u Define a template named SGPLOT_SCAT with Discrete Attribute Map Data set. -*;
proc template;
define statgraph SGPLOT_SCAT;
begingraph;
entrytitle 'Score Over Time by Treatment'/ textattrs=(size=2pct);
*- v Define the range attribute map and assign the name “BBMI_Range”. -*;
RangeAttrMap name="BBMI_Range";
range MIN - < 19 / rangecolor=BLUE;
range 19 - < 26 / rangecolormodel=(LIGHTPURPLE LIGHTORANGE);
range 26 - <30 / rangecolormodel=(LIGHTORANGE LIGHTRED);
range 30 - MAX / rangecolor=RED;
EndRangeAttrMap;
*- w Associate the attribute map with the variable BBMI and -*;
*- assign the variable name RANGEVAR for this association. -*;
RangeAttrVar attrvar=rangevar var=BBMI attrmap="BBMI_Range“ ;
76
76
77. Using Range Attribute Map with GTL Approach
*- v Define the range attribute map and assign the name “BBMI_Range”. -*;
RangeAttrMap name="BBMI_Range";
range MIN - < 19 / rangecolor=BLUE;
range 19 - < 26 / rangecolormodel=(LIGHTPURPLE LIGHTORANGE);
range 26 - <30 / rangecolormodel=(LIGHTORANGE LIGHTRED);
range 30 - MAX / rangecolor=RED;
EndRangeAttrMap;
Color Spectrum specifies
In Range Attribute Map.
77
77
78. Using Range Attribute Map with GTL Approach
*- v Define the range attribute map and assign the name “BBMI_Range”. -*;
RangeAttrMap name="BBMI_Range";
range MIN - < 19 / rangecolor=BLUE;
range 19 - < 26 / rangecolormodel=(LIGHTPURPLE LIGHTORANGE);
range 26 - <30 / rangecolormodel=(LIGHTORANGE LIGHTRED);
range 30 - MAX / rangecolor=RED;
EndRangeAttrMap;
Tick marks are as
specified in
Range Attribute
Map.
78
78
79. Using Range Attribute Map with GTL Approach
*- u Define a template named SGPLOT_SCAT with Discrete Attribute Map Data set. -*;
proc template; SGPLOT_SCAT
define statgraph;
begingraph;
entrytitle 'Score Over Time by Treatment'/ textattrs=(size=2pct);
Case-Sensitive! Must Match!
*- v Define the attribute map and assign the name “BBMI_Range”. -*;
RangeAttrMap name = "BBMI_Range“ ;
range MIN - < 19 / rangecolor=BLUE;
range 19 - < 26 / rangecolormodel=(LIGHTPURPLE LIGHTORANGE);
range 26 - <30 / rangecolormodel=(LIGHTORANGE LIGHTRED);
range 30 - MAX / rangecolor=RED;
EndRangeAttrMap;
*- w Associate the attribute map with the variable BBMI and -*;
*- assign the variable name RANGEVAR for this association. -*;
RangeAttrVar attrvar=rangevar var=BBMI attrmap="BBMI_Range“ ; 79
79
80. Using Range Attribute Map with GTL Approach (Continued)
*- x Define the Scatterplot Plot in the template. -*;
layout overlay;
scatterplot x=MONTH y=SCORE / markercolorgradient=rangevar
markerattrs=(symbol=circlefilled size=4px)
name="scatter“ ;
continuouslegend "scatter" / orient=vertical halign=right
title="BMI at Baseline";
endlayout;
endgraph;
end;
run;
*- yUse PROC SGRENDER to render the graph from stored graphics template SGPLOT.-*;
proc sgrender data=SCORE template=SGPLOT_SCAT ;
run;
80
80
81. Using Range Attribute Map with GTL Approach (Continued)
Case-Sensitive! Must Match!
*- x Define the Scatterplot Plot in the template. -*;
layout overlay;
scatterplot x=MONTH y=SCORE / markercolorgradient=rangevar
markerattrs=(symbol=circlefilled size=4px)
name="scatter“ ;
continuouslegend "scatter" / orient=vertical halign=right
title="BMI at Baseline";
endlayout;
endgraph;
end;
run;
*- yUse PROC SGRENDER to render the graph from stored graphics template SGPLOT.-*;
proc sgrender data=SCORE template=SGPLOT_SCAT ;
run;
81
81
83. A Multi-Cell Graph
In early Clinical Trials with
few subjects, often times
the interest is SAFETY of the
Study drug.
A Multi-Cell Graph is
Helpful to display the score
(usually lab results) of each
Subject.
84. A Multi-Cell Graph
A Multi-Cell Plot
Is generated by the
SGPANEL procedure.
Note here each subject
is listed according to the
subject’s Baseline BMI
and Subject ID. These
are the PANELBY
varaibles in PROC
SGPANEL.
87. Re-Visit the Default Line Attribute Inconsistency Graph
Subject 103 comes first
based on the subject’s Baseline
BMI and Subject ID. Therefore,
the line for this subject takes on
The first set of line attributes
(Red Line, Circle and
linestyle=1). Same applies for
the rest of the subjects until line
attributes have been assigned
to all treatments.
88. The Methods to resolve for Line Inconsistency in
PROC SGPLOT Also applies to PROC SGPANEL.
89. Consider the Distribute Attribute Map Method (Method 5A)
Create Attribute Map dataset.
data MYATTRMAP;
retain ID "MYID";
input VALUE & $7. linepattern : $3. LINECOLOR : $6. MARKERSYMBOL : $12.
markercolor : $6.;
cards;
Drug A 1 red circle red
Drug B 2 blue square blue
Drug C 3 green diamond green
Placebo 4 orange circlefilled orange
;
run;
91. And it works …
Our Line Attributes
are now consistent!
92. SLIDE PRESENTATION
A copy of this slide will be available at:
http://www.slideshare.net/alice_m_cheng
92
92
92
93. ACKNOWLEDGEMENT
Art Carpenter, Caloxy
Shawn Hopkin, Seattle Genetics
Sanjay Matange, SAS Institute
Lelia McConnell, SAS Technical Support
Steve Michaelson, SimulStat, Inc.
Susan Morrison, SAS Technical Support
Boyd Roloff, Chiltern International Ltd
Adam Sharp, SimulStat, Inc.
Marcia Surratt, SAS Technical Support
Jim Szymeczek, Chiltern International Ltd
93
93
94. Contact Information
Name: Alice Cheng
Enterprise: Chiltern International Ltd.
City, State: Bannockburn, IL
Work Phone: (650) 989-8645
E-mail: alice.cheng@chiltern.com
alice_m_cheng@yahoo.com
Web: http://www.chiltern.com
http://www.linkedin.com/in/alicemcheng
http://www.slideshare.net/alice_m_cheng
95. Contact Information
Name: Justina M. Flavin
Enterprise: SimulStat Inc.
City, State: San Diego, CA
E-mail: justin.flavin@gmail.com
Web: http://www.stimulstat.com