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.
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!
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.
Select SAS Training centers are offering in-person courses. View upcoming courses for: