When I use only a single grade, the order is how I want/expect - ordered by the data, year1 (sgplot1#1)
when I have two grades, the panel order changes for the grade=2 panels (sgplot#2), - any suggestions on how to keep the order?
data test;
input grade year1 year2 $ pct1 pct2;
cards;
1 1 t3 .3 .5
1 2 t4 .2 .5
2 1 t1 .2 .5
2 2 t2 .4 .5
2 3 t3 .2 .6
2 4 t4 .4 .7
;
run;
*#1;
data test1; set test; where grade = 2; run;
proc sort data= test1 ; by grade year1; run;
proc sgpanel data=test1;
panelby year2 / rows=2 columns=2 sort=data;
Scatter y = pct1 x = pct2 /; by grade;
run;
*#2;
proc sort data=test ; by grade year1; run;
proc sgpanel data=test CYCLEATTRS;
panelby year2 / rows=2 columns=2 sort=data;
Scatter y = pct1 x = pct2; by grade;
run;
thank you for the suggestions - it looks like I did a poor job expaining my problem.
My issue is that I need panelby ordered by year2 while sorting on year1 (I've got a number grades, year1's and year2's, and year1 is not always equal to year2, for different grades) - I thought using data=sort in the panelby statement would provide the order of panels, but it doesn't (it appears to want to replicate the order from the 1st bygroup)
I submitted the question to SAS Tech support, and it appears to be an internal problem. Their response:
--------------------------------------------------------
Since you're using a BY statement, the SGPANEL procedure appears to be performing an internal sort of the data that causes the panels to be in a different order.
I'll send this to development to fix for the future.
In the meantime, you can use a macro to run the SGPANEL procedure using a WHERE statement for each value of the BY variable rather than using a BY statement. For example:
proc sort data=test_sas ;
by grade y pct1 pct2;
run;
%macro panel(byval);
title "Grade=&byval";
proc sgpanel data=test_sas ;
where grade=&byval;
panelby year / rows=2 columns=2 NOVARNAME sort=data ;
Scatter y = pct1 x = pct2;
run;
%mend;
data _null_;
set test_sas;
by grade;
if first.grade then call execute('%PANEL(' || trim(grade) ||')');
run;
As an alternative to using the WHERE statement in PROC SGPANEL, you can create the graph using the Graph Template Language (GTL) with the DATAPANEL layout. For example:
ods path(prepend) work.template(update);
proc template;
define statgraph panels;
begingraph;
layout datapanels classvars=(year2) / rows=2 columns=2 headerlabeldisplay=value ;
layout prototype;
scatterplot y=pct1 x=pct2;
endlayout;
endlayout;
endgraph;
end;
run;
proc sort data=test_sas ; by grade y pct2; run;
proc sgrender data=test_sas template=panels; by grade;
run;
I am not quite sure why you sort by year1 but the use panel by year2.
In the specific data shown the order works for the grade 2 data because the Year1 and Year2 sort order would be the same.
Since for grade 1 you have year2 valures of t3 and t1 for year1 values of 1
Maybe you you need to sort by grade year2?
Based on your SGPANEL variable requests, the PROC SORT BY request should look like this:
proc sort data=test; by grade year2; run;
The YEAR1 variable should be dropped because it is not used in the graph. Also, remove the SORT=DATA from the PANELBY statement, as the order of the YEAR2 variable will already be maintained because the data has been properly presorted.
Hope this helps!
Dan
thank you for the suggestions - it looks like I did a poor job expaining my problem.
My issue is that I need panelby ordered by year2 while sorting on year1 (I've got a number grades, year1's and year2's, and year1 is not always equal to year2, for different grades) - I thought using data=sort in the panelby statement would provide the order of panels, but it doesn't (it appears to want to replicate the order from the 1st bygroup)
I submitted the question to SAS Tech support, and it appears to be an internal problem. Their response:
--------------------------------------------------------
Since you're using a BY statement, the SGPANEL procedure appears to be performing an internal sort of the data that causes the panels to be in a different order.
I'll send this to development to fix for the future.
In the meantime, you can use a macro to run the SGPANEL procedure using a WHERE statement for each value of the BY variable rather than using a BY statement. For example:
proc sort data=test_sas ;
by grade y pct1 pct2;
run;
%macro panel(byval);
title "Grade=&byval";
proc sgpanel data=test_sas ;
where grade=&byval;
panelby year / rows=2 columns=2 NOVARNAME sort=data ;
Scatter y = pct1 x = pct2;
run;
%mend;
data _null_;
set test_sas;
by grade;
if first.grade then call execute('%PANEL(' || trim(grade) ||')');
run;
As an alternative to using the WHERE statement in PROC SGPANEL, you can create the graph using the Graph Template Language (GTL) with the DATAPANEL layout. For example:
ods path(prepend) work.template(update);
proc template;
define statgraph panels;
begingraph;
layout datapanels classvars=(year2) / rows=2 columns=2 headerlabeldisplay=value ;
layout prototype;
scatterplot y=pct1 x=pct2;
endlayout;
endlayout;
endgraph;
end;
run;
proc sort data=test_sas ; by grade y pct2; run;
proc sgrender data=test_sas template=panels; by grade;
run;
Since none of your exampl sgpanel code uses or mentions the year1 variable at all then why does it require sorting by year1?
Yes it may be needed for a different step but not for the sgpanel code as shown. So resort afterwards to do the other steps, or possibly use two different data sets.
But is suspect that you meant originally but did not say so that you needed completely separate output for each level of year1.
Which is why we often say: SHOW what you want for the output and provide enough data that it the result is possible from the given data and the data is not trivial
SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!
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.