Hi there,
I am trying to reformat my output so that plots show up in a 2x2 format.
A little about the data: 200 health care clinics, each with an aspirin, blood pressure, cholesterol and smoking measurement.
Each clinic will have 4 plots (histograms) pending no missing data. As I have it coded now, the plots are outputted in a list. I would like them in a 2x2 panel and separated out by clinic.
I used Macros to generate the histograms because they were a bit atypical, heres an example code for smoking plot (PID is the ID variable)
%MACRO PLOT4(PID, clinicname, smoke_C, smokeBL, smoke_15);
TITLE "Plot for Smoking Cessation Measures with Baseline and 15 Month Markers for &clinicname (Practice ID &PID)";
PROC SGPLOT DATA=WORK.Numeric;
HISTOGRAM smoke_C / SHOWBINS BINSTART= 0 BINWIDTH = 0.05 ;
XAXIS LABEL = 'Smoking Cessation';
REFLINE &smokeBL/ AXIS=X LINEATTRS=(COLOR=RED THICKNESS=2) LABEL= "Baseline= &smokeBL" LABELPOS=MAX;
REFLINE &smoke_15/ AXIS=X LINEATTRS=(COLOR = RED THICKNESS=2) LABEL= "15 Month= &smoke_15" LABELPOS=MAX;
RUN;
%MEND;
The code for aspirin, blood pressure and cholesterol is the same -- I just substitute those variables into the macro variable.
How can I output theses 4 plots ( called %PLOT1 %PLOT2 %PLOT3 and %PLOT4 ) so that they are in a 2x2 panel?
Thank you for the help!
@aebabinec wrote:
Hi there,
I am trying to reformat my output so that plots show up in a 2x2 format.
A little about the data: 200 health care clinics, each with an aspirin, blood pressure, cholesterol and smoking measurement.
Each clinic will have 4 plots (histograms) pending no missing data. As I have it coded now, the plots are outputted in a list. I would like them in a 2x2 panel and separated out by clinic.
I used Macros to generate the histograms because they were a bit atypical, heres an example code for smoking plot (PID is the ID variable)
%MACRO PLOT4(PID, clinicname, smoke_C, smokeBL, smoke_15);
TITLE "Plot for Smoking Cessation Measures with Baseline and 15 Month Markers for &clinicname (Practice ID &PID)";
PROC SGPLOT DATA=WORK.Numeric;
HISTOGRAM smoke_C / SHOWBINS BINSTART= 0 BINWIDTH = 0.05 ;
XAXIS LABEL = 'Smoking Cessation';
REFLINE &smokeBL/ AXIS=X LINEATTRS=(COLOR=RED THICKNESS=2) LABEL= "Baseline= &smokeBL" LABELPOS=MAX;
REFLINE &smoke_15/ AXIS=X LINEATTRS=(COLOR = RED THICKNESS=2) LABEL= "15 Month= &smoke_15" LABELPOS=MAX;
RUN;
%MEND;
The code for aspirin, blood pressure and cholesterol is the same -- I just substitute those variables into the macro variable.
How can I output theses 4 plots ( called %PLOT1 %PLOT2 %PLOT3 and %PLOT4 ) so that they are in a 2x2 panel?
Thank you for the help!
If I understand what you want then likely you can modify your data slightly and use Proc SGPANEL. The key would be to transpose your data so you have a variable to indicate which type of measurement is involved and have a common variable to hold the numeric value.
data example; length measuretype $ 15; do clinic= 1 to 3; do MeasureType = 'Aspirin', 'Blood Pressure', 'Cholestorol','Smoking'; do i= 1 to 10; measurevalue = 100*rand('uniform'); output; end; end; end; run; proc sgpanel data=example; by clinic; panelby measuretype/columns=2 rows=2; histogram measurevalue ; run;
Another option would be to look at the Graphic Template language and Layout Gridded or Layout Lattice
Thanks for the suggestion. Given the data structure and the interdependency of variables this won't work. Maybe a different way to do it would be to insert the 4 graph macros into a display template...any ideas on how to do that?
it would somewhat like this:
---------------------------------
| | |
| %PLOT1 | %PLOT2 |
|_________|__________|
| | |
|%PLOT3 | %PLOT4 |
|_________|__________|
@aebabinec wrote:
Thanks for the suggestion. Given the data structure and the interdependency of variables this won't work. Maybe a different way to do it would be to insert the 4 graph macros into a display template...any ideas on how to do that?
it would somewhat like this:
---------------------------------
| | |
| %PLOT1 | %PLOT2 |
|_________|__________|
| | |
|%PLOT3 | %PLOT4 |
|_________|__________|
What won't work? That is pretty vague. Please be specific.
What "interdependency of variables"?
Did you actually modify data and look at the results?
It really helps to provide at least some data.
What destination are you sending the output to? @PGStats solution may be what you want for ease of implementation based on your current code.
Or perhaps look at this example:
proc template; define statgraph twoby; dynamic VAR1 var2 var3 var4; begingraph; layout lattice/columns=2 rows=2; layout overlay / ; histogram VAR1 / ; endlayout; layout overlay / ; histogram VAR2 / ; endlayout; layout overlay / ; histogram VAR3 / ; endlayout; layout overlay / ; histogram VAR4 / ; endlayout; endlayout; endgraph; end; run; proc sgrender data=sashelp.cars template=twoby; dynamic VAR1="Weight" var2='msrp' var3='Invoice' var4='enginesize'; run;
The dynamic variables mean that you place the names of the variables, in quotes, you want to graph so this should work with your data.
The ORDER of the graphed values would be changed by changing the order they appear in the proc sgrender dynamic statement.
I did try that but I am struggling with the reference lines...heres a data overview:
PID Clinic Name Aspirin aspirin_bl aspirin15 bloodp bloodp_bl bloodp_15 chol chol_bl chol_15 smoke smoke_bl smoke15
101 ajsjddjdjd 0.682 0.672 0.783 0.368 0.388 0.467 0.728 0.452 0.567 0.257 0.652 0.789
102 skskks
.
.
.
Essentially, aspirin, bloodp, chol, and smoke contain 6 measures for each clinic(so 1200 values). Aspirin_BL bloodp_bl, chol_bl and smoke_bl contain that clinics baseline (1st measure) and those variable with 15 are the clinics 6th measure (the baseline and 15 month variables only have 200 values each, one for each clinic). Therefore, the histograms are based on the aspirin, bloodp, chol, and smoke variables and the reference lines are for the clinics baseline and 15 month.
I hope this helps and I appreciate your help!
If the destination is HTML, PDF or Powerpoint, you could use
ODS LAYOUT GRIDDED columns=2 rows=2;
before calling your macro.
Note this is a relatively recent feature.
There are 4 macros (one for each graph) that I call in a DATA step:
DATA WORK.Graphs;
SET WORK.Numeric;
BY PID;
IF first.PID THEN CALL EXECUTE ('%PLOT1('||PID||','||clinicname|| ','||asprin||','||aspirin_BL ||','||aspirin15||')');
IF first.PID THEN CALL EXECUTE ('%PLOT2('||PID||','||clinicname|| ','||bp||','||bp_BL ||','||bp15||')');
IF first.PID THEN CALL EXECUTE ('%PLOT3('||PID||','||clinicname|| ','||chol_C||','||chol_BL ||','||chol_15||')');
IF first.PID THEN CALL EXECUTE ('%PLOT4('||PID||','||clinicname|| ','||smoke_C||','||smokeBL ||','||smoke_15||')');
RUN;
BUT, I would like to change the output so it is not in list format but rather looks like this:
a 2x2 template
---------------------------------
| | |
| %PLOT1 | %PLOT2 |
|_________|__________|
| | |
|%PLOT3 | %PLOT4 |
|_________|__________|
any suggestions?
Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 16. Read more here about why you should contribute and what is in it for you!
SAS' Charu Shankar shares her PROC SQL expertise by showing you how to master the WHERE clause using real winter weather data.
Find more tutorials on the SAS Users YouTube channel.