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
Where is the definition of macro cntlist?
I forgot to copy that over from my program. Whoops, it's:
%let cntlist = &sqlobs;
placed after proc sql and before the macro.
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
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)
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
Join us for SAS Innovate 2025, our biggest and most exciting global event of the year, in Orlando, FL, from May 6-9.
Early bird rate extended! Save $200 when you sign up by March 31.
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.
Ready to level-up your skills? Choose your own adventure.