Reputation:
I am trying to run through a large data set and create a simple scatter plot for each person. I would like to run this in SAS using a do loop and proc sgplot.
My dataset is the following:
Person Date QTY Brand
Jim | August 2015 | 20 | Pepsi
Jim | AUgust 2015 | 20 | Coke
Jim | October 2016 | 30 | Pepsi
Jim | November 2016 | 40 | Sprit
Susan | Sept. 2015 | 20 | Dr.Pepper
Susan | Dec. 2016 | 10 | Sprit
Helen | Jan. 2016 | 20 | Coke
Helen | Feb.2016 | 30 | Pepsi
There are many distinct people (n=100). I want to create a scatter plot for each unique person that shows the date on the x axis, and quantity on the y. Then I would like the points grouped by brand.
Currently my code is:
%do i =1 to count(distinct(Person));
proc sgplot data= Original (where=(count = 4))
scatter x=Date y=QTY/ group = Brand;
run;
end;
Any suggestions?
Upvotes: 1
Views: 1335
Reputation: 27508
In SAS, the doing something for each concept is typically serviced via the BY
statement. The Proc will perform the operations you expect and automatically process the data group-wise according to the distinct values of the by variable(s) !
This example demonstrates how the by
variable value can be placed in the plot title (#byval1
), as well as suppressing the default byline (nobyline
) that would show person=name as a sub-title. The BY PERSON
statement with the optional argument NOTSORTED
means the rows of the group will be formed row-wise by contiguous value adjacency, allowing by
processing to work without error even when the data is not sorted by Person
. For safer operation, presort or index the data set by the by variables first.
data have; infile datalines dlm='|';
input
Person $ Date: date11. QTY Brand $;
format date date9.;
datalines;
Jim | 01-Aug-2015 | 20 | Pepsi
Jim | 01-Aug-2015 | 20 | Coke
Jim | 01-Oct-2016 | 30 | Pepsi
Jim | 01-Nov-2016 | 40 | Sprit
Susan | 01-Sep-2015 | 20 | Dr.Pepper
Susan | 01-Dec-2016 | 10 | Sprit
Helen | 01-Jan-2016 | 20 | Coke
Helen | 01-Feb-2016 | 30 | Pepsi
run;
title "Scatter for #BYVAL1";
options nobyline;
proc sgplot data=have;
by person notsorted;
scatter x=date y=qty / group = brand;
xaxis interval=month;
format date monyy7.;
run;
options byline;
title;
persons Jim
Susan
Helen
are not in sort order, so if the NOTSORTED
option was left off there would be an error message and possibly some incomplete output.
Upvotes: 2
Reputation: 21274
You don't, you add a BY statement. You may need to sort the data ahead of time, by PERSON for this to work but BY group process is efficient.
proc sgplot data= Original (where=(count = 4));
BY PERSON;
scatter x=Date y=QTY/ group = Brand;
run;
Upvotes: 0
Reputation: 1103
To use a do-loop in that manner you will have to write the code within a macro. Also, to get the list of distinct people you can use proc sql's select into: feature.
%macro CreatePlots;
proc sql noprint;
select disinct person into: people separated by ' '
from original;
quit;
/* List of people in macro variable */
%put &people;
/* Loop over the list of people */
%do i=1 %to %sysfunc(countw(&people));
%let person = %scan(&people,&i);
/* Print the current person being plotted */
%put &=person;
proc sgplot data= Original(where=(person="&person"));
scatter x=Date y=QTY/ group = Brand;
run;
%end;
%mend;
%CreatePlots;
Upvotes: 1