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
April 27 – 30 | Gaylord Texan | Grapevine, Texas
Walk in ready to learn. Walk out ready to deliver. This is the data and AI conference you can't afford to miss.
Register now and lock in 2025 pricing—just $495!
Still thinking about your presentation idea? The submission deadline has been extended to Friday, Nov. 14, at 11:59 p.m. ET.
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.