12-05-2012 05:06 PM
I would like to implement a 2 level nested loop in SAS. Please see SAS pseudo code below.
I have a list of subject numbers held in the dataset "subjects" and a list of dataset names held in dataset "datatypes". Each of the datatypes referenced by the dataset "datatypes" would be an individual dataset.
pt = subjid;
dt = datatype;
* print all the data for the current pt and dt, eg, "select * from dt where subjid = pt"
Please note that its the code for the 2 level nested loop that I need and not the how to implement the specific code within the loops.
Thanks for your help.
12-05-2012 05:54 PM
I think it can be done this way, using a single MACRO variable (untested) :
select distinct dataType into :inCmd separated by " " from datatypes;
set &inCmd indsname=dataType;
select S.subjId as pt, D.dataType as dt, /* and whatever you need */
from subjects as S inner join allDataTypes as D on S.subjId=D.subjId;
12-05-2012 07:48 PM
The first step creates a list of the dataset names.
The second step reads and concatenates all those datasets in the list and creates a new variable called dataType to keep the name of the dataset that contributed each observation.
The third step is a query that joins the Subjects dataset with the allDataTypes dataset by pairing observations with the same subjId.
12-05-2012 06:50 PM
Why do you feel the need to nest it?
Sounds like you want to make a patient profile report.
One way is to create a macro that reports one patient then generate a call to the macro for each patient.
%local dslist ds i ;
%let dslist = dm ae ;
%do i=1 %to %sysfunc(countw(&dslist));
proc print data=&ds ;
filename code temp;
put '%patprofile(' ptid ');';
%inc code / source2 ;
12-05-2012 06:53 PM
It's not clear how general this needs to be, but here's another approach.
call execute('data ' || strip(datatype) || '; set subjects; run;');
If the requirements become really involved, this might get cumbersome. But it might do the job that you require. Here's another thought as well that begins the same as PGStats' suggestion:
proc sql noprint;
select distinct strip(datatype) into : dataset_list separated by ' ' from datatypes
Of course, this doesn't work if you need a more involved analysis, such as a PROC FREQ for each data set. But if that might be needed, there are definitely ways to loop through each data set name in a list. See how close you come to what you need with this much, and we can always embellish later.