This paper is an improved version of the WUSS 2011 paper of the same time. This paper covers the following:
(1). The Nature of the SGPLOT procedure.
How are Line Attributes assigned?
(2). The Legend (Line Inconsistency) problem.
(3). 5 Solutions to Line Attribute Inconsistency.
(4). Additional Comments on Attribute Maps.
Unlike earlier version of this paper, the current paper has more emphasis on Attribute Map and the SGPanel procedure was just mentioned/refered.
1. PharmaSUG 2012 - Paper DG12
IS THE LEGEND IN YOUR SAS/GRAPH®
OUTPUT STILL TELLING THE RIGHT
STORY?
Alice M. Cheng, South San Francisco, CA
Justina M. Flavin, SimulStat, Inc.
2. OBJECTIVES
To explore both traditional and the latest
approaches to ensure Legend Consistency
(or Line Attribute Consistency).
2
2 PharmaSUG 2012 - Paper DG12
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 Paper)
(Some Discussion on Attribute Map and SGPANEL Procedure)
(Second Edition, PharmaSUG 2012)
(More Emphasis on Attribute Map; SGPANEL Procedure was
only mentioned/referenced )
3
3 PharmaSUG 2012 - Paper DG12
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.
4
4 PharmaSUG 2012 - Paper DG12
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 PharmaSUG 2012 - Paper DG12
6. THE NATURE OF SGPLOT
HOW ARE LINES ATTRIBUTES (COLOR, SYMBOL
and STYLE) ASSIGNED?
6
6 PharmaSUG 2012 - Paper DG12
7. Treatment
Order is
based
on Input Data
Order in
PROC
SGPLOT.
Figure 1A: Average Scores of 4 Treatments Over Time
7
7 PharmaSUG 2012 - Paper DG12
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 PharmaSUG 2012 - Paper DG12
9. 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.
9
9 PharmaSUG 2012 - Paper DG12
10. 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.
10
10
10 PharmaSUG 2012 - Paper DG12
11. 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 9.3, you have to
sort by the Group (TRT) variable.
11
11
11 PharmaSUG 2012 - Paper DG12
12. 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.
12
12
12 PharmaSUG 2012 - Paper DG12
13. 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.
13
13
13 PharmaSUG 2012 - Paper DG12
15. LINE ATTRIBUTES
Line Attributes (line color, symbol and style).
Drug A
Drug B
Drug C
Placebo
It is critical that line attributes are CONSISTENT.
15
15
15 PharmaSUG 2012 - Paper DG12
16. 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.
16
16
16 PharmaSUG 2012 - Paper DG12
17. Error!!!
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.
17
17
17 PharmaSUG 2012 - Paper DG12
18. THE FIGURE WE WANT …
Average
Note: The lines in the legend are consistent with the lines when
all 4 treatments are available.
18
18
18 PharmaSUG 2012 - Paper DG12
19. 5 SOLUTIONS TO RESOLVE
LEGEND INCONSISTENCY ISSUES
19
19
19 PharmaSUG 2012 - Paper DG12
20. SOLUTION # 1
USE DUMMY DATA
20
20
20 PharmaSUG 2012 - Paper DG12
21. Solution # 1. Use Dummy Data
data DUMMY;
length TRT $7.;
TRT=‘Drug A’; MONTH= . ; SCORE= . ; output;
Create a Dummy
TRT=‘Drug B’; MONTH= . ; SCORE= . ; output;
TRT=‘Drug C’; MONTH= . ; SCORE =. ; output; Dataset for all
TRT=‘Placebo’; MONTH= . ; SCORE =.; output; Treatment groups.
run;
data DRUG_WT_DUMMY;
set DUMMY Append DRUG data at
DRUG (where=(TRT ne ‘Drug B’) ); the end of DUMMY data
run; to retain the correct
Treatment group order.
*- Generate Figure 3A. -*;
ods listing style=STYLES.MYSTYLE;
proc sgplot data=DRUG_WT_DUMMY;
series y=SCORE x=MONTH / group=TRT markers; Use data from
keylegend / noborder title=‘Treatment’; run; To create Figure 3A.
21
21
21 PharmaSUG 2012 - Paper DG12
22. 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.
22
22
22 PharmaSUG 2012 - Paper DG12
23. SOLUTION # 2
RE-MAP LINE ATTRIBUTES
23
23
23 PharmaSUG 2012 - Paper DG12
24. 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.
24
24
24 PharmaSUG 2012 - Paper DG12
25. Solution # 2. RE-MAP LINE ATTRIBUTE
*- 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;
25
25
25 PharmaSUG 2012 - Paper DG12
26. Solution # 2. RE-MAP LINE ATTRIBUTE
*- 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;
%*- 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;
26
26
26 PharmaSUG 2012 - Paper DG12
27. Solution # 2. RE-MAP LINE ATTRIBUTE
%*- 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;
%*- 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;
27
27
27 PharmaSUG 2012 - Paper DG12
28. Solution # 2. RE-MAP LINE ATTRIBUTE
*- 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;
28
28
28 PharmaSUG 2012 - Paper DG12
29. 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.
29
29
29 PharmaSUG 2012 - Paper DG12
30. SOLUTION # 3
RE-CODE INTERNAL VALUES
OF GROUP VARIABLE
30
30
30 PharmaSUG 2012 - Paper DG12
31. 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.
31
31
31 PharmaSUG 2012 - Paper DG12
32. 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.
32
32
32 PharmaSUG 2012 - Paper DG12
33. 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.
33
33
33 PharmaSUG 2012 - Paper DG12
34. Solution # 3. RE-CODE INTERNAL VALUES OF GROUP VARIABLE
*- 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;
34
34
34 PharmaSUG 2012 - Paper DG12
35. Solution # 3. RE-CODE INTERNAL VALUES OF GROUP VARIABLE
*- 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; Resign new internal numeric
set DRUG (where=(TRT ne ‘Drug b’) ); values to TRT2.
TRT2=input(TRT, intrf.);
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;
35
35
35 PharmaSUG 2012 - Paper DG12
36. Solution # 3. RE-CODE INTERNAL VALUES OF GROUP VARIABLE
*- 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.
36
36
36 PharmaSUG 2012 - Paper DG12
37. Solution # 3. RE-CODE INTERNAL VALUES OF GROUP VARIABLE
*- 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;
37
37
37 PharmaSUG 2012 - Paper DG12
38. Solution # 3. RE-CODE INTERNAL VALUES OF GROUP VARIABLE
*- 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.
38
38
38 PharmaSUG 2012 - Paper DG12
39. 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.
39
39
39 PharmaSUG 2012 - Paper DG12
40. SOLUTION # 4
USE INDEX OPTION IN
x
GRAPH TEMPLATE LANGUAGE (GTL)
40
40
40 PharmaSUG 2012 - Paper DG12
41. 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
41
41
41 PharmaSUG 2012 - Paper DG12
42. Use of Index Options in GTL Can Ensure Line Consistency
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.
42
42
42 PharmaSUG 2012 - Paper DG12
43. Use of Index Options in GTL Can Ensure Line Consistency
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.
Example:
proc sgplot data=DRUG
tmplout=“c:alicepharmasug_2012_graphline_plot.sas”;
series y=SCORE x=MONTH / group=TRT markers;
keylegend/noborder title=‘Treatment: ‘;
run;
43
43
43 PharmaSUG 2012 - Paper DG12
44. Solution # 4. USING INDEX IN GTL
*- 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;
44
44
44 PharmaSUG 2012 - Paper DG12
45. Solution # 4. USING INDEX IN GTL
*- 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;
45
45
45 PharmaSUG 2012 - Paper DG12
46. Solution # 4. USING INDEX IN GTL
*- 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;
46
46
46 PharmaSUG 2012 - Paper DG12
47. Solution # 4. USING INDEX IN GTL
*- 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;
*- 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; 47
endgraph; Add Manually.
47 run;
end;
47 PharmaSUG 2012 - Paper DG12
48. Solution # 4. USING INDEX IN GTL
*- 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.
48
48
48 PharmaSUG 2012 - Paper DG12
49. 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.
49
49
49 PharmaSUG 2012 - Paper DG12
50. SOLUTION # 5
USE OF ATTRIBUTE MAP
(Available in SAS Version 9.3)
50
50
50 PharmaSUG 2012 - Paper DG12
51. 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
51
51 PharmaSUG 2012 - Paper DG12
52. SOLUTION # 5A
USE OF SG ATTRIBUTE MAP
(Available in SAS Version 9.3)
52
52
52 PharmaSUG 2012 - Paper DG12
53. Solution # 5A. Using SG Attribute Map Approach
*- 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;
*- 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;
53
53
53 PharmaSUG 2012 - Paper DG12
54. 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.
54
54
54 PharmaSUG 2012 - Paper DG12
55. SOLUTION # 5B
USE OF ATTRIBUTE MAP
WITH GTL APPROACH
(Available in SAS Version 9.3)
55
55
55 PharmaSUG 2012 - Paper DG12
56. Solution # 5B. Using Attribute Map with GTL Approach
*- 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);
*- 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;
*- Associate the attribute map with input data column ID and -*;
*- assign the name GROUPMARKERS to named association. -*;
DiscreteAttrVar attrvar=groupmarkers var=TRT attrmap=“lineattr” ;
56
56 PharmaSUG 2012 - Paper DG12
57. Solution # 5B. Using Attribute Map with GTL Approach
*- 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!
*- 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;
*- Associate the attribute map with input data column ID and -*;
*- assign the name GROUPMARKERS to named association. -*;
DiscreteAttrVar attrvar=groupmarkers var=TRT attrmap=“lineattr” ;
57
57 PharmaSUG 2012 - Paper DG12
58. Solution # 5B. Using Attribute Map with GTL Approach
*- 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);
*- 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!
*- Associate the attribute map with input data column ID and -*;
*- assign the name GROUPMARKERS to named association. -*;
DiscreteAttrVar attrvar=groupmarkers var=TRT attrmap=“lineattr” ;
58
58 PharmaSUG 2012 - Paper DG12
59. Solution # 5B. Using Attribute Map with GTL
Approach (Continued)
*- 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;
*- 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; 59
59 PharmaSUG 2012 - Paper DG12
60. Solution # 5B. Using Attribute Map with GTL Approach (Continued)
Case-Sensitive! Must Match!
*- 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;
*- 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; 60
60 PharmaSUG 2012 - Paper DG12
61. 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.
61
61
61 PharmaSUG 2012 - Paper DG12
62. Which of the 5 approaches should be applied?
A Quick Peek Only?
YES NO
Use Method 1: Have SAS 9.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
62 PharmaSUG 2012 - Paper DG12
63. 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.
63 PharmaSUG 2012 - Paper DG12
64. 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.
64 PharmaSUG 2012 - Paper DG12
66. Attribute Map
Discrete Range
Attribute Map Attribute Map
Using SG Using Using
Procedures GTL GTL
66 PharmaSUG 2012 - Paper DG12
67.
Attribute Map
Discrete Range
Attribute Map Attribute Map
Using SG Using Using
Procedures GTL GTL
= Already Discussed.
67 PharmaSUG 2012 - Paper DG12
68. Discrete To display discrete value.
Attribute Map Example: Treatment Groups
68 PharmaSUG 2012 - Paper DG12
69. 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)
69 PharmaSUG 2012 - Paper DG12
70. 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)
70 PharmaSUG 2012 - Paper DG12
71. 4 Categories based on BMI:
BMI at Baseline Category
(kg/m2)
< 19 Underweight
19 - < 26 Normal
26 - < 30 Overweight
>= 30 Obese
71 PharmaSUG 2012 - Paper DG12
72. 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.
72 PharmaSUG 2012 - Paper DG12
73. Using Range Attribute Map with GTL Approach
*- 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);
*- 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;
*- 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“ ;
73
73 PharmaSUG 2012 - Paper DG12
74. Using Range Attribute Map with GTL Approach
*- 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.
t
t
74
74 PharmaSUG 2012 - Paper DG12
75. Using Range Attribute Map with GTL Approach
*- 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.
t
t
75
75 PharmaSUG 2012 - Paper DG12
76. Using Range Attribute Map with GTL Approach
*- 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);
Case-Sensitive! Must Match!
*- 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;
*- 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 PharmaSUG 2012 - Paper DG12
77. Using Range Attribute Map with GTL Approach (Continued)
*- 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;
*- Use PROC SGRENDER to render the graph from stored graphics template SGPLOT.-*;
proc sgrender data=SCORE template=SGPLOT_SCAT ;
run;
77
77 PharmaSUG 2012 - Paper DG12
78. Using Range Attribute Map with GTL Approach (Continued)
Case-Sensitive! Must Match!
*- 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;
*- Use PROC SGRENDER to render the graph from stored graphics template SGPLOT.-*;
proc sgrender data=SCORE template=SGPLOT_SCAT ;
run;
78
78 PharmaSUG 2012 - Paper DG12
79. ACKNOWLEDGEMENT
Art Carpenter, Caloxy
Shawn Hopkin, Seattle Genetics
Lelia McConnell, SAS Technical Support
Steve Michaelson, SimulStat, Inc.
Susan Morrison, SAS Technical Support
Adam Sharp, SimulStat, Inc.
Marcia Surratt, SAS Technical Support
79
79
79 PharmaSUG 2012 - Paper DG12
80. SLIDE PRESENTATION
A copy of this slide will be available at:
http://www.slideshare.net/alice_m_cheng
80
80
80 PharmaSUG 2012 - Paper DG12
81. Contact Information
Alice M. Cheng
South San Francisco, CA
E-mail: alice_m_cheng@yahoo.com
http://
www.linkedin.com/in/alicemcheng
81
81 PharmaSUG 2012 - Paper DG12
82. Contact Information
Justina M. Flavin
SimulStat Inc., San Diego, CA
E-mail: justina.flavin@gmail.com
82
82 PharmaSUG 2012 - Paper DG12