BookmarkSubscribeRSS Feed
lsandell
Obsidian | Level 7

Hi there, I am writing a macro loop to run univariate tests and output test 3 results to datasets. This loop is intended for a large dataset where I have too many variables to include in individual macro calls. I want to run 2 different modeling frameworks based on the format applied to numeric variables. Right now, the format (i.e., &fmtlist) is not being considered and my 0/1 variables that have the Y. format (0="no", 1="yes") applied are not being run within the logistic regression PROC. Any ideas for why this is being ignored?

 

I do not get any error messages, but my results are incorrect as all my "numeric" variables are being fed into the PROC GLM, despite having my Y. format applied.

 

Additionally, I would like to append all the results together into one dataset. I need to figure that out, once I get the correct results to be output. 

 

Thanks!

proc format library = form.formats;
value y
.= 'Missing'
0= 'No'
1= 'Yes'
;
run;

proc contents data = x varnum out=variable_list; run;
data variable_list; length format $1.; set variable_list; run; proc sql noprint select name,type,format into :varlist separated by ' ', :typelist separated by ' ', :fmtlist separated by ' ' from variable_list; quit; %let cntlist = &sqlobs;
%macro univar; %do i=1 %to %cntlist; %if %scan(&typelist, &i)=1 %then %do; %if %scan(&fmtlist, &i)="Y" %then %do; proc logistic data = &data; format %scan(&varlist, &i) y.; class %scan(&varlist, &i) (ref=FIRST) / param = ref; model outcome(event="Y") = %scan(&varlist, &i); ods output modelANOVA = nfit&i; run; %end; %else %if %scan(&fmtlist, &i) ne "Y" %then %do; proc glm data = &data; class outcome (ref="N") / param = ref; model %scan(&varlist, &i) = exposure; ods output modelANOVA = cfit&i; quit; %end; %end; %else %if %scan(&typelist, &i)=2 %then %do; proc logistic data = &data; class %scan(&varlist, &i) (ref=FIRST) / param = ref; model outcome(event="Y") = %scan(&varlist, &i); ods output modelANOVA = cfit&i; run; %end; %end; %mend univar; %univar;

first values from the log: %put &fmtlist; $ $ Y $ $ Y Y 

8 REPLIES 8
lsandell
Obsidian | Level 7

I forgot to copy that over from my program. Whoops, it's:
%let cntlist = &sqlobs;

placed after proc sql and before the macro.

PaigeMiller
Diamond | Level 26

This is a situation where LOOKING AT the data, in this case SAS data set VARIABLE_LIST would likely solve your program as you can see what values are in the variable named FORMAT, and it is these values which become part of macro variable &FMTLIST.

 

Alternatively, you could simply have the macro processor display in the log the values of macro variable &FMTLIST. 

%put &=fmtlist;

 

So, LOOK AT this macro variable or the original data. What do you see? Can you show it to us?

 

This line

 

 

%if %scan(&fmtlist, &i)="Y" %then %do;

 

 

probably will never work, unless the i-th element of &fmtlist is "Y", including the quotes, and Y must be capitalized. Is any element of &fmlist "Y"? I don't think so, you are deriving &fmtlist from format names a provided by PROC CONTENTS, and none of the formats are going to be "Y".

 

This line

 

 

%else %if %scan(&fmtlist, &i) ne "Y" %then %do;

 

 

will likely always cause the PROC GLM to execute as there are likely no values of the macro variable &fmtlist that are equal to "Y" (including the double quotes and with capital Y).

 

What will work? I don't know, you haven't shown us the values in &fmtlist

--
Paige Miller
lsandell
Obsidian | Level 7
I do see Y in the &fmtlist output in the log. I placed in quotes as it is character.

I can't edit my original post to include the log contents, so here is an excerpt of the first values from the log: %put &fmtlist; $ $ Y $ $ Y Y .
PaigeMiller
Diamond | Level 26

Y is not "Y"

 

%macro dothis;
%let var=Y;
%if &var="Y" %then %put Value is Equal;
%mend;
%dothis

 

No quotes required here, macro processing treats all text as text, even if they look like numbers. The %if in your code is testing to see if the macro variable is equal to the three characters "Y" (double quote-Y-double quote)

--
Paige Miller
lsandell
Obsidian | Level 7
Ah, that makes sense. Thank you for clarifying the macro processing details.
ballardw
Super User

Not every data set will actually have a FORMAT reported by Proc Contents.

Run this an look at the values in the FORMAT variable of the output data set:

proc contents data =sashelp.class varnum out=variable_list; run;

That is an indication of default formats for each variable type. So for what appears to be your purpose before adding a value to the "list" you have to make sure there is one, and likely check if the variable type is numeric and use BEST and CHAR if character (or B and C).

 

What is the purpose of extracting the first letter of a format to begin with? Sounds pretty hokey for any usage.

Base64

Binary ( and you need a type to tell if you want the Character or Numeric version)

B8601 (about two dozen flavors)

Best

 

 

Reeza
Super User
Did you run the macro with symbolgen and mprint options on? If so, what does the log show for those steps where it errors out?

Ready to join fellow brilliant minds for the SAS Hackathon?

Build your skills. Make connections. Enjoy creative freedom. Maybe change the world. Registration is now open through August 30th. Visit the SAS Hackathon homepage.

Register today!
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.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 8 replies
  • 747 views
  • 0 likes
  • 5 in conversation