Reputation: 1764
I have a data set that looks like this:
data have;
input name $ class $ time score;
cards;
chewbacca wookie 1 97
chewbacca wookie 2 100
chewbacca wookie 3 95
saruman wizard 1 79
saruman wizard 2 85
saruman wizard 3 40
gandalf wizard 1 22
gandalf wizard 2 50
gandalf wizard 3 87
bieber canadian 1 50
bieber canadian 2 45
bieber canadian 3 10
;
run;
I'm creating a program that does two things: 1. prints the data for each distinct class 2. creates a scatterplot x=time y=score for each name.
Executing the code below will illustrate my desired output:
data chewbacca saruman gandalf bieber;
set have;
if name='chewbacca' then output chewbacca;
else if name='saruman' then output saruman;
else if name='gandalf' then output gandalf;
else if name='bieber' then output bieber;
run;
title 'Report for wookie';
proc print data=have;
where class='wookie';
run;
title 'Plot Chewbacca';
proc sgplot data=chewbacca;
scatter x=time y=score;
run;
title 'Report for wizard';
proc print data=have;
where class='wizard';
run;
title 'Plot Saruman';
proc sgplot data=saruman;
scatter x=time y=score;
run;
title 'Plot Gandalf';
proc sgplot data=gandalf;
scatter x=time y=score;
run;
title 'Report for canadian';
proc print data=have;
where class='canadian';
run;
title 'Plot Bieber';
proc sgplot data=bieber;
scatter x=time y=score;
run;
Ideally, I'd like to automate this. I've been trying to set this up, but am missing something. Here is my attempt:
proc sql;
select count(distinct name) into :numname
from have;
%let numname=&numname;
select distinct name into :name1 - :name&numname
from have;
select count(distinct class) into :numclass
from have;
%let numclass=&numclass;
select distinct class into :class1 - :class&numclass
from have;
quit;
%macro printit;
%do i = 1 %to &numclass;
title 'Report for &&class&i';
proc print data=have;
where class=&&class&i;
run;
/*insert sgplot here*/
%end;
%mend;
%printit;
Please help here. Can't get the syntax sorted....
Thanks.
Upvotes: 1
Views: 582
Reputation: 974
The print
procedure and most ODS procedures support by-group processing, which might be a lot simpler and save a lot of time depending on what you require.
proc sort data=have; by class;
proc print data=have;
by class;
run;
and
proc sort data=have; by name;
proc sgplot data=have;
by name;
scatter x=time y=score;
run;
Upvotes: 1
Reputation: 12465
I see 4 issues.
Macros will only resolve inside double quotes. Single quotes mask the resolution. So change the title statement to:
title "Report for &&class&i";
The class variable is a string. You need to quote the string in the where clause:
where class="&&class&i";
You don't need to generate the separate data sets. You can add a where clause when you specify the data for SGPLOT
proc sgplot data=have(where=(name="&&name&i"));
The number of names and classes are different, so you need two loops.
EDIT: Also look at SGPANEL
and/or SGRENDER
. You can generate all the charts in 1 call.
Upvotes: 6