BookmarkSubscribeRSS Feed
code_blooded
Fluorite | Level 6

Hi all,

 

I'm using the below code to generate an automated SAS output as a dataset from proc GLM. I have 14 outcome variables on which I need to run the same model. I was hoping. I am able to get the output like I want for one variable. However with my current code when I run it for all 14 variables, the outputs get stacked on top of each other and there is no way to tell which set of estimates correspond to which SAS variable. The transpose procedure marks estimates and p-values from 1-14 and I currently cross check with the SAs output in the results viewer to verify the correct outcome and solution.  I was hoping if I would be able to add the name of the outcome variable in my output dataset. It'd be a lot more easier for me. I have highlighted the specific part (text in blue) where I want to insert it. Is there a way for SAS to automatically set the value of the variable outcome as the  name of the outcome variable that it's currently running??

 

 

 

 

%macro MODEL1acpo (yvar1a, out1a);
*the below is to output the table that we refer to as a dataset;
ods output ParameterEstimates = data1(keep=parameter estimate Probt); /*ods choose the wanted output tables IN THIS CASE EFFECT WHICH TELLS THE VARIABLE NAME, ESTIMATE AND P-VALUE */
*this is the actual model, Change outcome variable is the only macro variable here;
proc glm data= cleft.cleft_cleaned; class childsex (ref='1') race_col (ref='1') furlow (ref='0') second_pal_surg (ref='0');
model &yvar1a = childage childsex race_col sf_SES_score complete_incom age_pripalate dem_4cp_surgeries furlow second_pal_surg/solution clparm;
where cleft_dx_new= 1 and adopt= 0; title 'Hyp 1A: Parent Model CPO &yvar1a'; title; run;
*This is clening up the output dataset to round off the estimates and probablity tables;
data &out1a; set data1; where parameter ne 'Intercept' and estimate ne 0; /* output estimate, 95%CI and p-value*/
estimate_= round (estimate, 0.01);
if (0.04 < Probt < 0.06) then probt_ = round (probt, 0.001);
else probt_= round (probt, 0.01);
drop estimate probt; rename estimate_= estimate probt_= probt;

outcome= &yvar1a;
run;
%mend model1acpo;
%let outcomes= cbcltotpraw cbclepraw cbclipraw cbcltcraw cbclschraw cbclaraw cbclsraw cbcladhraw cbclafpraw cbclanpraw cbclsompraw cbclodpraw cbclcpraw cbclptsraw;

%model1acpo (&outcomes, Output_1a_CPO);
proc sort data= Output_1a_CPO; by parameter; run;
proc transpose data=Output_1a_CPO out=estimate_wide name=variable prefix=Estimate; by parameter;
var estimate; /* transpose the table from long to wide format*/
run;
proc transpose data=Output_1a_CPO out=p_wide name=variable prefix=P_value; by parameter;
var probt; /* transpose the table from long to wide format*/
run;
Proc sort data= estimate_wide; by parameter; run;
Proc sort data= p_wide; by parameter; run;
data model1_output; merge estimate_wide p_wide; by parameter; run;

 

 

Thanks for helping!! 

9 REPLIES 9
ballardw
Super User

Two things, define a constant length for the OUTCOME variable , then use quotes.

 

length outcome $ 32;

outcome ="&yvar1a";

 

The length is so when you combine data sets at some point you don't have issues with different lengths of the variable causing warnings and/or truncation of data.

The quotes are needed to assign a character value. Just like Somevar = "Abc";

 

code_blooded
Fluorite | Level 6

Hi Thank you so much for responding to my post. I tried your suggestion but instead of giving me the specific outcome for which SAS is running the program; it gives me the list of outcomes as the values of the variable. 

PaigeMiller
Diamond | Level 26

First problem, which is not a Macro related problem: 

 

OUTCOME= is not a valid statement in PROC GLM.

 

So this will never work, regardless of how correct your macro code is. Important advice: First, you need working code without macros and without macro variables for one value of &OUTCOMES hardcoded into your PROC GLM. Clearly you haven't done that, or you'd know that this won't work. So your real first task is to create working PROC GLM code for one value of &outcomes hard-coded. Normally, when we tell people to do this, they just ignore us and keep going, as if this is unimportant, but it it extremely important to writing working macros.

 

Second problem:

 

The macro processor cannot read your mind. It doesn't know to loop over all the values in &outcomes. Why? because the macro processor thinks the value of macro variable &YVAR1A is simply text and nothing more. If you want it to loop, you have to specifically tell the macro processor to do a loop. Which still won't make your code work until you fix the first problem, as I described.

 

 

--
Paige Miller
ballardw
Super User

@PaigeMiller 

 

The Outcome= is buried in poorly structured data step code. He is using ODS Output to create a data set and then wants to add the variable to that data and save in a new data set (at least that's how I read this).

PaigeMiller
Diamond | Level 26

@ballardw wrote:

@PaigeMiller 

 

The Outcome= is buried in poorly structured data step code. He is using ODS Output to create a data set and then wants to add the variable to that data and save in a new data set (at least that's how I read this).


Okay, thanks, @ballardw , I see that now, but the advice remains ... get this to work for one hardcoded value of &OUTPUT and only then try to turn it into a macro.

--
Paige Miller
code_blooded
Fluorite | Level 6

Hi Paige,

 

Thanks for responding to my post. I tried running it for one code it works perfectly fine. It works perfect even for the list of outcomes I specified. The only issue I'm facing is that I'm trying to improve my output data code so that in the output dataset it is easier for me to identify which set of parameter estimates belong to which variable. The current output looks like this: 

code_blooded_0-1624469621720.png

 

PaigeMiller
Diamond | Level 26

@code_blooded wrote:

Hi Paige,

 

Thanks for responding to my post. I tried running it for one code it works perfectly fine. It works perfect even for the list of outcomes I specified. The only issue I'm facing is that I'm trying to improve my output data code so that in the output dataset it is easier for me to identify which set of parameter estimates belong to which variable. The current output looks like this: 

code_blooded_0-1624469621720.png

 


Use the suggestion from Tom at https://communities.sas.com/t5/SAS-Programming/How-to-use-macro-to-assign-a-value-to-a-variable/m-p/...no macros needed.

--
Paige Miller
Tom
Super User Tom
Super User

Why not just use add another transpose so you can just use BY in your PROC call?

So instead of a wide dataset with N independent variables and 12 dependent variables make a dataset with N+2 variables and 12 times as many observations.  The extra two variables will be the NAME and VALUE of 12 different dependent variables.

 

Now use NAME in the BY statement and VALUE as the dependent variable in the MODEL statement.

PaigeMiller
Diamond | Level 26

@Tom wrote:

Why not just use add another transpose so you can just use BY in your PROC call?

So instead of a wide dataset with N independent variables and 12 dependent variables make a dataset with N+2 variables and 12 times as many observations.  The extra two variables will be the NAME and VALUE of 12 different dependent variables.

 

Now use NAME in the BY statement and VALUE as the dependent variable in the MODEL statement.


So to translate the excellent suggestion above into "Paige-speak", I would say: "no macros needed". How simple is that?

--
Paige Miller

SAS Innovate 2025: Save the Date

 SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!

Save the date!

How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

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
  • 9 replies
  • 1188 views
  • 9 likes
  • 4 in conversation