I have a dummy dataset with 3 cohorts: 1, 2 and 3. In each cohort there are subjects (Cohort 1: 011, 012. Cohort2: 021. Cohort 3: 031). I want the keylegend to show 3 rows with row 1 "Cohort 1: 011 012", row 2 "Cohort 2: 021", and row 3 "Cohort 3: 031". I don't know how. Below is the data and plot.
data test; cohort = 1;subjid = '011';aval = 10; ady = 1; output; cohort = 1;subjid = '012';aval = 15; ady = 1; output; cohort = 2;subjid = '021';aval = 20; ady = 2; output; cohort = 3;subjid = '031';aval = 30; ady = 3; output; run; proc sort data=test; by cohort subjid; run; proc sgpanel data=test; panelby cohort / columns=1 spacing=5 novarname HEADERATTRS=(Family=Arial Size=11 Weight=Bold); series x=ady y=aval / markers group=subjid markerattrs=(symbol=circle) ; keylegend /title='Subject' titleattrs=(size=8 family='Arial' weight=bold); colaxis offsetmin=0.05 offsetmax=0.01 values=(-1 1 2 3 ) valueattrs=(weight=bold size=8 family='Arial') valuesdisplay=('Baseline' 'Day 1' 'Day 2' 'Day 3') label='Study Day' labelattrs=(weight=bold size=11 family='Arial') fitpolicy=rotate; rowaxis label="Param" labelattrs=(weight=bold family='Arial' size=11); refline 1 / axis=x lineattrs=(thickness=1 color=lightgray pattern=solid); run;
I think this comes close to what you are asking for.
Separate legends sort of imply separate plots. So the data is changed to plot a different y variable in each plot panel. Then use the EXCLUDE= option for each separate keylegend to only show the subjid for the cohort.
data test; cohort = 1;subjid = '011';aval = 10; ady = 1; output; cohort = 1;subjid = '012';aval = 15; ady = 1; output; cohort = 2;subjid = '021';aval2 = 20; ady = 2; output; cohort = 3;subjid = '031';aval3 = 30; ady = 3; output; run; proc sort data=test; by cohort subjid; run; proc sgpanel data=test; panelby cohort / columns=1 spacing=5 novarname HEADERATTRS=(Family=Arial Size=11 Weight=Bold); series x=ady y=aval / markers group=subjid markerattrs=(symbol=circle) name='p1' ; series x=ady y=aval2 / markers group=subjid markerattrs=(symbol=circle) name='p2' ; series x=ady y=aval3 / markers group=subjid markerattrs=(symbol=circle) name='p3' ; keylegend 'p1' /title='Corhort 1' exclude=('021' '031') titleattrs=(size=8 family='Arial' weight=bold); keylegend 'p2' /title='Corhort 2' exclude=('011' '012' '031') titleattrs=(size=8 family='Arial' weight=bold); keylegend 'p3' /title='Corhort 3' exclude=('011' '012' '021') titleattrs=(size=8 family='Arial' weight=bold); colaxis offsetmin=0.05 offsetmax=0.01 values=(-1 1 2 3 ) valueattrs=(weight=bold size=8 family='Arial') valuesdisplay=('Baseline' 'Day 1' 'Day 2' 'Day 3') label='Study Day' labelattrs=(weight=bold size=11 family='Arial') fitpolicy=rotate; rowaxis label="Param" labelattrs=(weight=bold family='Arial' size=11); refline 1 / axis=x lineattrs=(thickness=1 color=lightgray pattern=solid); run;
There might be a cleaner way with Annotate data.
Hi Ballardw,
Thanks a lot for help! It works!
The actual data has about many cohorts. Each cohort has 3 subjects. It would be tedious to exclude so many subjects in reality.
data test;
cohort = 1;subjid = '011';aval = 10; ady = 1; output;
cohort = 1;subjid = '012';aval = 15; ady = 1; output;
cohort = 2;subjid = '021';aval = 20; ady = 2; output;
cohort = 3;subjid = '031';aval = 30; ady = 3; output;
run;
proc sort data=test; by cohort subjid; run;
proc sgpanel data=test;
panelby cohort / columns=1 spacing=5 novarname HEADERATTRS=(Family=Arial Size=11 Weight=Bold);
series x=ady y=aval / markers group=subjid markerattrs=(symbol=circle) ;
legenditem name='a' type=MARKERLINE / label='011' MARKERATTRS=graphdata1 LINEATTRS=graphdata1;
legenditem name='b' type=MARKERLINE / label='012' MARKERATTRS=graphdata2 LINEATTRS=graphdata2;
legenditem name='c' type=MARKERLINE / label='021' MARKERATTRS=graphdata3 LINEATTRS=graphdata3;
legenditem name='d' type=MARKERLINE / label='031' MARKERATTRS=graphdata4 LINEATTRS=graphdata4;
keylegend 'a' 'b' /title='Corhort 1' titleattrs=(size=8 family='Arial' weight=bold) noborder;
keylegend 'c' /title='Corhort 2' titleattrs=(size=8 family='Arial' weight=bold) noborder;
keylegend 'd' /title='Corhort 3' titleattrs=(size=8 family='Arial' weight=bold) noborder;
colaxis offsetmin=0.05 offsetmax=0.01 values=(-1 1 2 3 ) valueattrs=(weight=bold size=8 family='Arial')
valuesdisplay=('Baseline' 'Day 1' 'Day 2' 'Day 3')
label='Study Day' labelattrs=(weight=bold size=11 family='Arial') fitpolicy=rotate;
rowaxis label="Param" labelattrs=(weight=bold family='Arial' size=11);
refline 1 / axis=x lineattrs=(thickness=1 color=lightgray pattern=solid);
run;
Thanks a lot, KSharp!
Yes, it solves this problem.
But in reality, the study has about 50 subjects with 15 cohort. How to make legend item list easier to code?
Another information: if each cohort is 3 subjects, crossover = 3 will make it multiple rows in 3 columns. But how to add cohort label "Cohort 1", "Cohort 2" etc?
@jsbyxws wrote:
Thanks a lot, KSharp!
Yes, it solves this problem.
But in reality, the study has about 50 subjects with 15 cohort. How to make legend item list easier to code?
Another information: if each cohort is 3 subjects, crossover = 3 will make it multiple rows in 3 columns. But how to add cohort label "Cohort 1", "Cohort 2" etc?
That would likely be ugly in SGPANEL.
Did you try SGPLOT:
Consider that with a BY statement then each legend is built separately and by default each plot will have the By information:
data test; cohort = 1;subjid = '011';aval = 10; ady = 1; output; cohort = 1;subjid = '012';aval = 15; ady = 1; output; cohort = 2;subjid = '021';aval = 20; ady = 2; output; cohort = 3;subjid = '031';aval = 30; ady = 3; output; run; proc sort data=test; by cohort subjid; run; proc sgplot data=test; by cohort; /* panelby cohort / columns=1 spacing=5 novarname HEADERATTRS=(Family=Arial Size=11 Weight=Bold);*/ series x=ady y=aval / markers group=subjid markerattrs=(symbol=circle) ; keylegend /title='Subject' titleattrs=(size=8 family='Arial' weight=bold); xaxis offsetmin=0.05 offsetmax=0.01 values=(-1 1 2 3 ) valueattrs=(weight=bold size=8 family='Arial') valuesdisplay=('Baseline' 'Day 1' 'Day 2' 'Day 3') label='Study Day' labelattrs=(weight=bold size=11 family='Arial') fitpolicy=rotate; yaxis label="Param" labelattrs=(weight=bold family='Arial' size=11); refline 1 / axis=x lineattrs=(thickness=1 color=lightgray pattern=solid); run;
Thanks! I will give it a try.
Registration is now open for SAS Innovate 2025 , our biggest and most exciting global event of the year! Join us in Orlando, FL, May 6-9.
Sign up by Dec. 31 to get the 2024 rate of just $495.
Register now!
Learn how use the CAT functions in SAS to join values from multiple variables into a single value.
Find more tutorials on the SAS Users YouTube channel.
Ready to level-up your skills? Choose your own adventure.