How can I output multiple HISTOGRAM image files with BY in PROC UNIVARIATE? Suppose I have the following panel data set.
data _;
do i=1 to 5;
do t=1 to 5;
x=rannor(1);
output;
end;
end;
run;
I tried the following code, but it just overwrote the destination file five times.
filename _ "!userprofile\desktop\_.png";
goption gsfname=_ device=png gsfmode=replace;
ods results=off;
proc univariate noprint;
var x;
by i;
histogram/normal(noprint);
run;
ods results=on;
Here is the log.
11 filename _ "!userprofile\desktop\_.png"; 12 goption gsfname=_ device=png gsfmode=replace; 13 ods results=off; 14 proc univariate noprint; 15 var x; 16 by i; 17 histogram/normal(noprint); 18 run; NOTE: 11265 bytes written to C:\Users\Junyong\desktop\_.png. NOTE: The above message was for the following BY group: i=1 NOTE: 11665 bytes written to C:\Users\Junyong\desktop\_.png. NOTE: The above message was for the following BY group: i=2 NOTE: 10306 bytes written to C:\Users\Junyong\desktop\_.png. NOTE: The above message was for the following BY group: i=3 NOTE: 11258 bytes written to C:\Users\Junyong\desktop\_.png. NOTE: The above message was for the following BY group: i=4 NOTE: 10640 bytes written to C:\Users\Junyong\desktop\_.png. NOTE: The above message was for the following BY group: i=5 NOTE: PROCEDURE UNIVARIATE used (Total process time): real time 0.65 seconds cpu time 0.65 seconds 19 ods results=on;
Is there any way to collect the five HISTOGRAMs separately?
Proc UNIVARIATE uses ODS Graphics
You can achieve this as follows:
data have;
do i=1 to 5;
do t=1 to 5;
x=rannor(1);
output;
end;
end;
run;
ods _all_ close;
ods listing gpath="c:\temp";
ods graphics on;
ods graphics / reset=index imagefmt=png imagename="hist_#byval(i)";
title "Histogram for #byline";
proc univariate data=have noprint;
var x;
by i;
histogram/normal(noprint) odstitle=title;
/* format i z3.;*/
run;
title;
Some notes on the code.
If you need an image per seperate histogram my suggestion would be using a macro like this:
%macro multiple_outputs(i);
filename _&i. "!userprofile\desktop\_&i..png";
goption gsfname=_ device=png gsfmode=replace;
ods results=off;
data work.temp;
set _;
where i = &i.;
run;
proc Univariate noprint;
var x;
by i;
histogram/normal(noprint);
run;
ods results=on;
%mend multiple_outputs;
data _null_;
set _;
by i;
if first.i then
do;
arg1 = '%nrstr(%multiple_outputs('!!i!!'));';
call execute(arg1);
end;
run;
But I believe somebody will have a solution without having to fall back on macro code which would be a better solution, but I don't know one. I hope this helps you anyways.
Kind Regards
Criptic
Proc UNIVARIATE uses ODS Graphics
You can achieve this as follows:
data have;
do i=1 to 5;
do t=1 to 5;
x=rannor(1);
output;
end;
end;
run;
ods _all_ close;
ods listing gpath="c:\temp";
ods graphics on;
ods graphics / reset=index imagefmt=png imagename="hist_#byval(i)";
title "Histogram for #byline";
proc univariate data=have noprint;
var x;
by i;
histogram/normal(noprint) odstitle=title;
/* format i z3.;*/
run;
title;
Some notes on the code.
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.