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

So I want to run PROC MIXED in a macro loop.  I know don't say it.:smileyshocked:

I code ODS OUTPUT with presist=proc and I get my tables stacked together that's all good and there are two variables _PROC_ and _RUN_ that seem to suggest that they are to help me know which run of the proc each row is associated with but they all have the same value.  Is there a way I can control the value of these variables thought the PROC or other ODS statement?

Obs    _Proc_    _Run_ 
1    Mixed       1   
2    Mixed       1   
3    Mixed       1   
4    Mixed       1   
5    Mixed       1   
6    Mixed       1   
7    Mixed       1   
8    Mixed       1   
9    Mixed       1   
10    Mixed       1   

Accepted Solutions
Jade | Level 19

What would be nice (and would address your original thought) is a way to capture the current value of a macro variable in an ODS table.  It's all about getting something useful in the _RUN_ variable.  Man, if I had that, it would clean up so much work around code...

Steve Denham

View solution in original post

Obsidian | Level 7

Hi Data_null

I think that  _Proc_ will give you always the name of the used procedure.

If you persist  with models  through glm and reg then you get   GLM  and Reg  values  in that variable.

for _Run_  , i obtained increasing values  (1 2 3) when i have tried different successive models in one same proc (catmod by example)

You are certainly  submitting repeating mixed procedures.



Obsidian | Level 7

The only control that i can see is after:  reworking  the generated  values

Jade | Level 19

This is what I'm going to do.

  • ODS output tablename(persist=proc match_all=match)
  • Create a view with a dummy by variable that contains the %DO index value.
  • Stack it all back together with &match
  • Be carefull there is no truncation.
Jade | Level 19

This is close to what we do, but your approach using the persist= option is something we may want to look into.

Basically here is our approach:

  1. Create empty datasets to accumulate all ODS output, using whatever method works (I just use data alltables; stop;)
  2. Create an indexing variable on the dataset that will match the counter for the %DO index value
  3. Use a where statement in the PROC MIXED call to subset the analysis to the indexed value, and a by statement that includes the variable name on the dataset.
  4. Then after ODS outputs a table, with an indexed name, set it with the alltables dataset.

Probably not the most elegant method, but it gives what I think you are going after.

Steve Denham

Jade | Level 19

Sounds like you're doing pretty much the same thing as me.  I'm running a repeated measures model with a list of covariates that are include in the model one at a time.  I don't create the empty data sets as you do, I'm not sure I need them.  Here's my code such as it is and out of context but you get the idea.

      data _null_;
set &m._covariate end=eof;
         if not direct then class = covariate;
         call symputx(cats('covariate',_n_),covariate,'LOCAL');
         call symputx(cats('class',_n_),class,'LOCAL');
         if eof then call symputx('covariate0',_n_);

%if not &debug %then %do;
ods select none;

ods output
persist=proc match_all=match1)=&m._LSMEst_01
persist=proc match_all=match2)=&m._contrasts_01
persist=proc match_all=match3)=&m._tests_01
      %do i = 1 %to &covariate0;
         data &m._workV / view=&m._workV;
            length covariate $32 covindx 8;
retain covariate "&&covariate&i" covindx &i;
            set &m._working;
proc mixed data=&m._workV;
            by covariate covindx;
            class %unquote(&class) &&class&i;
            model &analvar = &trt|&repeated &covars &&covariate&i / &modelopts;
            repeated &repeated / &repeatedopts subject=&subject;
            %inc FT58F001 / source2;
            %inc FT58F002 / source2;
ods output close;

data &m._lsmest;
         length label $128;
set &match1;
data &m._contrasts;
         set &match2;
data &m._tests;
         set &match3;
Jade | Level 19

I think the logic is identical.  The empty dataset is just to avoid an error in the log when we start accumulating over several dependent variables for later reporting.  I think we could adapt part of this, esp. the match_all= option, and the idea of using a view rather than a whole new dataset to insert the indexing variable will definitely help.

There needs to be a way to give credit for an answer that comes up in the course of the discussion.  If I had been asking something, it would definitely be marked "Correct".

Steve Denham

Jade | Level 19

With MATCH_ALL SAS helps keeps track of the data sets that are created which is very helpful.  You do get this NOTE telling you that you no longer need to use MATCH_ALL but it doesn't mention that the new way may not include enough information to solve the newly created stacked data puzzle.

NOTE: MATCH_ALL=MATCH1 is no longer needed if your goal is to create a single data set containing all the variables in all the identified objects. By default, if the ODS OUTPUT statement identifies
      multiple output objects, ODS now combines all the objects into a single data set that contains all the variables from all the

I think the question is still un-answered.  We just discussed our work-around. I think since they are almost identical they must be the "correct" work-around. Smiley Happy

It would be nice to get some input from someone at SI.

Jade | Level 19

What would be nice (and would address your original thought) is a way to capture the current value of a macro variable in an ODS table.  It's all about getting something useful in the _RUN_ variable.  Man, if I had that, it would clean up so much work around code...

Steve Denham


Available on demand!

Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.


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
  • 8 replies
  • 1 like
  • 3 in conversation