BookmarkSubscribeRSS Feed
Mikeyjh
Calcite | Level 5

Hi all,

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.

Data _null_;

     set subjects;

     pt = subjid;

     Data _null_;

          set datatypes;

          dt = datatype;

          * print all the data for the current pt and dt, eg, "select * from dt where subjid = pt"

      Run;

Run;

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.

5 REPLIES 5
PGStats
Opal | Level 21

I think it can be done this way, using a single MACRO variable (untested) :

proc sql;

select distinct dataType into :inCmd separated by " " from datatypes;

quit;

data allDatatypes;

set &inCmd indsname=dataType;

run;

proc sql;

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;

drop allDataTypes;

quit;

PG

PG
Mikeyjh
Calcite | Level 5

Thanks for your reply PG.

Can you explain what your allDataTypes statement does especially the "indsname=dataType"?

PGStats
Opal | Level 21

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.

Hth.

PG

PG
Tom
Super User Tom
Super User

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.

%macro patprofile(ptid);

%local dslist ds i ;

%let dslist = dm ae ;

%do i=1 %to %sysfunc(countw(&dslist));

  %let ds=%scan(&dslist,&it);

  proc print data=&ds ;

    where ptid=&ptid;

  run;

%end;

%mend patprofile;

filename code temp;

data _null_;

  set patlist;

  put '%patprofile(' ptid ');';

run;

%inc code / source2 ;

Astounding
PROC Star

It's not clear how general this needs to be, but here's another approach.

data _null_;

   set datatypes;

   call execute('data ' || strip(datatype) || '; set subjects; run;');

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

quit;

data &dataset_list;

   set subjects;

run;

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.

Good luck.

SAS Innovate 2025: Register Now

Registration is now open for SAS Innovate 2025 , our biggest and most exciting global event of the year! Join us in Orlando, FL, May 6-9.
Sign up by Dec. 31 to get the 2024 rate of just $495.
Register now!

What is Bayesian Analysis?

Learn the difference between classical and Bayesian statistical approaches and see a few PROC examples to perform Bayesian analysis in this video.

Find more tutorials on the SAS Users YouTube channel.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 5 replies
  • 1287 views
  • 1 like
  • 4 in conversation