BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
MLaVenia
Calcite | Level 5

I'm using proc glimmix and need to model ~50 different outcomes. I recognize that I could just copy/paste the same code 50 times and change the outcome variable in each; however, it seems to me that SAS likely has a more eligant way of handling this. Does anyone know of a command or macro that basically says, "now, do that again, except this time with this outcome...and then this outcome"? Thanks, Mark

1 ACCEPTED SOLUTION

Accepted Solutions
SteveDenham
Jade | Level 19

Something like:

/* dataset prep goes here */

%macro RMANCOVA(param=);

/* any preprocessing data steps go in here */

proc glimmix data=for_Stats1 ;

where param = &param;

by param ;

class sex grp_no studyday anml_nbr ;

   model value = grp_no

                          sex

          studyday

        grp_no*sex

        sex*studyday

                          grp_no*studyday

        grp_no*sex*studyday

                        cov/ ddfm=kr2;

/* more glimmix code if needed */

run;

/* a bunch of reporting data steps to do things like accumulate tests, lsmeans, lsmestimates, etc here */

%mend RMANCOVA;

%macro MAIN;

  %do i=1 %to 21; 
      %RMANCOVA(param = &i);

  %end;

%mend MAIN;


%main;

This does 21 analyses with identical outcomes.  It requires preprocessing the data set into 'long' format, with all of the outcomes put into the variable 'value', and an additional variable 'param' that indexes the variables of interest.

Steve Denham

View solution in original post

9 REPLIES 9
AncaTilea
Pyrite | Level 9

Hi Mark.

Yes, there is a way (there are probably plenty).

One way would be to define a macro:

%macro models(outcome = );

     proc glimmix data = ....;

     model &outcome. = .....;

     run;

%mend models;

Then you could call the macro

%models(outcome = y1);

%models(outcome = y2)..

all the way to the fiftieths outcome.

Or,

you could save your outcomes of interest in a macro variable, then use a scan function...

So,

proc sql;

     select name into: my_outcomes separated by " "

     from dictionary.columns

     where libname = "WORK" & memname = "YOUR_DATASET_IN_CAPITAL_LETTERS"

     & name ....  ---at this point it would be nice if your outcome has some sort of pattern...

quit;

then change a bit the macro:

%macro models(outcome = );

%do i = 1 %to 50;

     proc glimmix data = ....;

     model %scan(&outcome., &i., "") = .....;

     run;

%mend models;

That's all.

Anca.

MLaVenia
Calcite | Level 5

Hi Anca and Steve - Thank you for your prompt replies. This is definitely going to require me to up my game, but your directions seem clear and detailed enough that I think I can figure it out. I'll reply later with a progress report.Gratefully yours, Mark

SteveDenham
Jade | Level 19

Something like:

/* dataset prep goes here */

%macro RMANCOVA(param=);

/* any preprocessing data steps go in here */

proc glimmix data=for_Stats1 ;

where param = &param;

by param ;

class sex grp_no studyday anml_nbr ;

   model value = grp_no

                          sex

          studyday

        grp_no*sex

        sex*studyday

                          grp_no*studyday

        grp_no*sex*studyday

                        cov/ ddfm=kr2;

/* more glimmix code if needed */

run;

/* a bunch of reporting data steps to do things like accumulate tests, lsmeans, lsmestimates, etc here */

%mend RMANCOVA;

%macro MAIN;

  %do i=1 %to 21; 
      %RMANCOVA(param = &i);

  %end;

%mend MAIN;


%main;

This does 21 analyses with identical outcomes.  It requires preprocessing the data set into 'long' format, with all of the outcomes put into the variable 'value', and an additional variable 'param' that indexes the variables of interest.

Steve Denham

data_null__
Jade | Level 19

Why do you use BY PARAM and WHERE PARAM=

Why not just use BY PARAM.   No macro loop involved.

SteveDenham wrote:

Something like:

/* dataset prep goes here */

%macro RMANCOVA(param=);

/* any preprocessing data steps go in here */

proc glimmix data=for_Stats1 ;

where param = &param;

by param ;

class sex grp_no studyday anml_nbr ;

   model value = grp_no

                          sex

          studyday

        grp_no*sex

        sex*studyday

                          grp_no*studyday

        grp_no*sex*studyday

                        cov/ ddfm=kr2;

/* more glimmix code if needed */

run;

/* a bunch of reporting data steps to do things like accumulate tests, lsmeans, lsmestimates, etc here */

%mend RMANCOVA;

%macro MAIN;

  %do i=1 %to 21; 
      %RMANCOVA(param = &i);

  %end;

%mend MAIN;


%main;

This does 21 analyses with identical outcomes.  It requires preprocessing the data set into 'long' format, with all of the outcomes put into the variable 'value', and an additional variable 'param' that indexes the variables of interest.

Steve Denham

SteveDenham
Jade | Level 19

We used to use the BY PARAM.  We ran into a problem with the random number string when using the adjust= option in the LSMEANS statement, in that we weren't duplicating p-values exactly even with a fixed seed when running on separate machines (don't ask, it's what we do to meet some GLP requirements) or when we wanted to look at one particular param that was indexed farther down the line, and compared its results to when it was analyzed "in sequence'.  This syntax enables re-initiating the random string with the designated seed.  Well, at least adding the WHERE statement eliminated the problem.  We could probably now use just the WHERE.

Steve Denham

data_null__
Jade | Level 19

Yes I see.  If you keep BY statement do the ODS output data have the BY variable included.  That would make it easier to put it all back together or keep is "sorted".

SteveDenham
Jade | Level 19

Yep.  I remember dropping the BY, and not having variable names/labels for reporting...

Steve Denham

MLaVenia
Calcite | Level 5

Hi Steve - It ran like a dream the first time; unheard of! Thank you so much. Best, Mark

Patrick
Opal | Level 21

Cynthia uses to call macro language the "automatic typewriter" - sorry Cynthia in case I've quoted you wrongly.

So what you describe "copy/paste the same code 50 times and change the outcome variable in each" sounds exactly like something you want to pack into a SAS macro.

I don't know anything about PROC GLIMMIX except that this is one of these statistic "black magic" procedures.

But on a general level what you could do for repetitive code blocks where only the variable name changes, is something like:

%macro CodeSnippet(variable);

     code code code;

     code &variable;

     code code code;

%mend;

Proc Whatever;

%CodeSnippet(var1);

%CodeSnippet(var2);

%CodeSnippet(var3);

... and so on.

run;

sas-innovate-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

Register now!

What is ANOVA?

ANOVA, or Analysis Of Variance, is used to compare the averages or means of two or more populations to better understand how they differ. Watch this tutorial for more.

Find more tutorials on the SAS Users YouTube channel.

Discussion stats
  • 9 replies
  • 1822 views
  • 4 likes
  • 5 in conversation