user10745594
user10745594

Reputation:

How Do I Write A Do-Loop That Creates A Graph For Each Unique Person?

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

Answers (3)

Richard
Richard

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

Reeza
Reeza

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

J_Lard
J_Lard

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

Related Questions