BookmarkSubscribeRSS Feed
tnmahmoo
Fluorite | Level 6

Hello,

 

I hope you are doing well.

 

I would like to request some of your time to help me with a note message that might be a problem, but I cannot resolve the message after hours of researching.

 

Note message is “variable is uninitialized”.

 

The SAS program package I am working on is from the Dietary Screener Questionnaire that was provided by NIH cancer institute.

 

I am very new to SAS and I have been using online resources plus this community forum to help me get this far in the coding.

 

I attached the content as a word doc because I wanted to give you as much detail as possible to understand where I need help in the coding. I hope you can open it. If not, please let me know.

 

Please help me figure out how to resolve the note message. I really appreciate your time and efforts in helping me, thank you!

9 REPLIES 9
SASKiwi
PROC Star

The variable is uninitialized SAS note indicates that this variable contains no data - the variable is not populated with non-missing data in any row. You can prove this for yourself by running the following program (please put your actual dataset and variable name in this code before running):

 

proc freq data = have;
  table VarAllMissing / missing;
run;

 

PGStats
Opal | Level 21

Those variables (hccerxpd, milkxpd, etc.) are not present in your SBMDdata dataset. To get a list of the variables in the dataset :

 

proc contents data=SBMDdata; run;
PG
Kurt_Bremser
Super User

Hi and welcome!

 

Please post code in a window opened with the "little running man" icon, and logs and/or external data from text files in a window opened with the {i} icon.

This makes it immediately visible and does away with the need to load Office files from the intenet. Many of us can't or won't do that for security reasons.

 

Your date step code either

  • tries to use a variable that is not present in one of the input datasets
  • creates a new variable (ie with length or format, or implicit by using it on the right side of an assignment) and never assigns a value to it.
tnmahmoo
Fluorite | Level 6

@SASKiwi@PGStats and @Kurt_Bremser thank you so much for responding! 

 

@Kurt_Bremser thank you for showing me how to insert code in this forum appropriately. I have now inserted the same code that is seen in the attachment from the first message. 

 

Ok so these sets of codes concern me because they supposedly streamline so that the variable names change as we progress through the codes. @PGStats you are right, SBMDdata file did not contain the variable names listed in the third code set. When I changed them to the right variable name that exists in the actual SBMDdata file, the code runs without issues. BUT this does not make sense based on the previous coding. From my understanding, the codes build on each other from the first to the last one down.

 

This makes me think that my codes are not as good as I thought. The first and second code sets are supposed to change the original response to a numeric. The third code set is to create a foodrange macro variable with the given parameters in parentheses. 

 

My questions now are

 

1. Are the code sets below doing what I think they are doing?

 

2. If yes to #1, then why does the third code not work as is?

 

3. I know how to code a proc print command but how do I do that for a macro statement? I want to do a print command to double check each of these codes as that has been my method to double check my work so far.

 

Thank you so much for your time and efforts! Learning SAS through troubleshooting this specific program package has been a journey!

 

data dtq;
set SBMDdata;
%macro foodrange (in,out,maxv);
%if in= 'A' %then;
%put &out=0;
%if &in='B' %then;
%put &out=0.033;
%if &in='C' %then;
%put &out=0.083;
%if &in='D' %then;
%put &out=0.143;
%if &in='E' %then;
%put &out=0.286;
%if &in='F' %then;
%put &out=0.5;
%if &in='G' %then;
%put &out=0.786;
%if &in='H' %then;
%put &out=1;
%if &in='I' %then;
%put &out=2;
%if &out > &maxv %then;
%put &out=&maxv;
%mend foodrange;
run;

NOTE: There were 61 observations read from the data set WORK.SBMDDATA.
NOTE: The data set WORK.DTQ has 61 observations and 34 variables.
NOTE: DATA statement used (Total process time):
      real time           0.03 seconds
      cpu time            0.01 seconds

data dtq;
set SBMDdata;
%macro bevrange (in,out,maxv);
%if &in='A' %then;
%put &out=0;
%if &in='B' %then;
%put &out=0.033;
%if &in='C' %then;
%put &out=0.083;
%if &in='D' %then;
%put &out=0.143;
%if &in='E' %then;
%put &out=0.286;
%if &in='F' %then;
%put &out=0.5;
%if &in='G' %then;
%put &out=0.786;
%if &in='H' %then;
%put &out=1;
%if &in='I' %then;
%put &out=2.5;
%if &in='J' %then;
%put &out=4.5;
%if &in='K' %then;
%put &out=6;
%if &out > &maxv %then;
%put &out=&maxv;  
%mend bevrange;
run;

NOTE: There were 61 observations read from the data set WORK.SBMDDATA.
NOTE: The data set WORK.DTQ has 61 observations and 34 variables.
NOTE: DATA statement used (Total process time):
      real time           0.06 seconds
      cpu time            0.03 seconds

data dtq;
set SBMDdata;
  %foodrange(dsq_010,hccerxpd,7);
  %bevrange(dsq_030,milkxpd,10);
  %bevrange(dsq_040,sodaxpd,8);
  %bevrange(dsq_050,frtjcxpd,8);
  %bevrange(dsq_060,swtctxpd,10);
  %bevrange(dsq_070,energyxpd,7);
  %foodrange(dsq_080,fruitxpd,8);
  %foodrange(dsq_090,saladxpd,5);
  %foodrange(dsq_100,frfryxpd,5);
  %foodrange(dsq_110,othpotxpd,3);
  %foodrange(dsq_120,beanxpd,4);
  %foodrange(dsq_130,othvegxpd,5);
  %foodrange(dsq_140,pizzaxpd,2);
  %foodrange(dsq_150,salsaxpd,3);
  %foodrange(dsq_160,tomscxpd,2);
  %foodrange(dsq_190,cheesexpd,6);
  %foodrange(dsq_200,whgbrdxpd,6);
  %foodrange(dsq_210,brricexpd,4);
  %foodrange(dsq_220,candyxpd,8);
  %foodrange(dsq_230,donutxpd,5);
  %foodrange(dsq_240,cakexpd,7);
  %foodrange(dsq_250,icecrmxpd,5);
  %foodrange(dsq_260,popcornxpd,3);
  run;
Kurt_Bremser
Super User

This code can't be the cause of an "uninitialized" message, as it does effectively nothing apart from writing messages to the log with the many %put's.

 

Follow the straight path of macro development:

  1. get Base SAS code running without any macro elements (eg for one item)
  2. identify the parts that need to be flexible
  3. replace those with macro variables, set the macro variables with %let, and test again
  4. wrap the code that needs to be dynamic into a macro definition and include the macrovars as macro parameters, test again
  5. use dynamically, or for multiple calls

But it all starts with working Base SAS code; unless you have that, there's nothing where the macro can be of any use.

Tom
Super User Tom
Super User

1. Are the code sets below doing what I think they are doing?

 What do you think they are doing?  Essentially you placed a macro definition inside of a data step and then never called the macro.  Since the macro processor operates on the program text first and then passes the resulting text to SAS to interpret that is is the same as defining the macro and then running the data step.

 

Is that what you wanted to do?

2. If yes to #1, then why does the third code not work as is?

Since your macros are not generating any actual SAS code placing calls to them into the middle of another data step will have the same problem as your first two data steps.  You could just as easily called the macros before (or without) the data step and gotten the same result.

 

Are you trying to generate actual SAS statements to become part of these data steps?  What statements to you want to generate?

tnmahmoo
Fluorite | Level 6

Thank you @Tom and @Kurt_Bremser for responding!

 

@Kurt_Bremser I will attempt the steps you have laid out. Your response led me to search for other sources to gain a better idea, these websites were a bit helpful:

http://support.sas.com/documentation/cdl/en/mcrolref/62978/HTML/default/viewer.htm#n18fij8dqsue9pn1l...

 

http://www2.sas.com/proceedings/sugi29/243-29.pdf

 

Below are my responses to @Tom and I have inserted the code again to help those reading these posts later to follow along...

 

@Tom I would like the first two code sets to replace the responses A-I with the numerical values listed. I do realize that this code is not specific in relation to the SBMDdata (a csv database with all of my observations and variables that I inserted at the beginning of my SAS coding). I think what I need to do is delete the data steps that are coded with the macro statements, replace %put with %let and then figure out how to make the macro statements specific to the variables that the code is related to. Foodrange macro statement is only relevant for certain variables within SBMDdata and same thing for bevrange. 

In the third code set, next to either %foodrange and %bevrange in parenthesis are "dsq_010, dsq_030, etc." those are the variable names found in SBMDdata file.

 

I think what I need to do is figure out a way to tell the macro statements to only replace responses within the designated dsq variable names but I do not know how to do that....am I on the right track? Did I miss something?? 

 

Thank you so much for your time and efforts!

 

data dtq;
set SBMDdata;
%macro foodrange (in,out,maxv);
%if in= 'A' %then;
%put &out=0;
%if &in='B' %then;
%put &out=0.033;
%if &in='C' %then;
%put &out=0.083;
%if &in='D' %then;
%put &out=0.143;
%if &in='E' %then;
%put &out=0.286;
%if &in='F' %then;
%put &out=0.5;
%if &in='G' %then;
%put &out=0.786;
%if &in='H' %then;
%put &out=1;
%if &in='I' %then;
%put &out=2;
%if &out > &maxv %then;
%put &out=&maxv;
%mend foodrange;
run;

NOTE: There were 61 observations read from the data set WORK.SBMDDATA.
NOTE: The data set WORK.DTQ has 61 observations and 34 variables.
NOTE: DATA statement used (Total process time):
      real time           0.03 seconds
      cpu time            0.01 seconds

data dtq;
set SBMDdata;
%macro bevrange (in,out,maxv);
%if &in='A' %then;
%put &out=0;
%if &in='B' %then;
%put &out=0.033;
%if &in='C' %then;
%put &out=0.083;
%if &in='D' %then;
%put &out=0.143;
%if &in='E' %then;
%put &out=0.286;
%if &in='F' %then;
%put &out=0.5;
%if &in='G' %then;
%put &out=0.786;
%if &in='H' %then;
%put &out=1;
%if &in='I' %then;
%put &out=2.5;
%if &in='J' %then;
%put &out=4.5;
%if &in='K' %then;
%put &out=6;
%if &out > &maxv %then;
%put &out=&maxv;  
%mend bevrange;
run;

NOTE: There were 61 observations read from the data set WORK.SBMDDATA.
NOTE: The data set WORK.DTQ has 61 observations and 34 variables.
NOTE: DATA statement used (Total process time):
      real time           0.06 seconds
      cpu time            0.03 seconds

data dtq;
set SBMDdata;
  %foodrange(dsq_010,hccerxpd,7);
  %bevrange(dsq_030,milkxpd,10);
  %bevrange(dsq_040,sodaxpd,8);
  %bevrange(dsq_050,frtjcxpd,8);
  %bevrange(dsq_060,swtctxpd,10);
  %bevrange(dsq_070,energyxpd,7);
  %foodrange(dsq_080,fruitxpd,8);
  %foodrange(dsq_090,saladxpd,5);
  %foodrange(dsq_100,frfryxpd,5);
  %foodrange(dsq_110,othpotxpd,3);
  %foodrange(dsq_120,beanxpd,4);
  %foodrange(dsq_130,othvegxpd,5);
  %foodrange(dsq_140,pizzaxpd,2);
  %foodrange(dsq_150,salsaxpd,3);
  %foodrange(dsq_160,tomscxpd,2);
  %foodrange(dsq_190,cheesexpd,6);
  %foodrange(dsq_200,whgbrdxpd,6);
  %foodrange(dsq_210,brricexpd,4);
  %foodrange(dsq_220,candyxpd,8);
  %foodrange(dsq_230,donutxpd,5);
  %foodrange(dsq_240,cakexpd,7);
  %foodrange(dsq_250,icecrmxpd,5);
  %foodrange(dsq_260,popcornxpd,3);
  run;
Tom
Super User Tom
Super User

You have missed the point about the difference between macro logic and SAS code.  The macro processor is just a tool that is usually used to generate SAS code.  But your macros are not generating any SAS code. They just have macro statements, not an SAS statements.

Let's look a the first few lines of your first macro. 

%if in= 'A' %then;

The first %IF is comparing the letters in to the an uppercase A enclosed in single quotes. Those two strings can never be equal.  Also even if there it was possible for the condition to be true there is nothing between the %THEN and the semi-colon so nothing would be happen if it was true. 

%put &out=0;

This %PUT line will write the value of the OUT parameter an equal sign and the digit zero to the SAS log.  Might help make it clearer in the SAS log what input was passed to the macro, but it will have no effect on anything.

 

%if &in='B' %then;

Now this %IF condition has a chance to be true, if you called the macro with the IN parameter set to an uppercase B enclosed in single quotes. But, like the other one, it also doesn't do anything when it is true. 

%foodrange (in='B');

 

What are you trying to do.  Show a small example input dataset and what output dataset you want.

 

Are you trying to re-code letters into numbers?  So in terms of SAS statements (not macro code) you might want to generate something like

if dsq_010='A' then hccerxpd=0;
else if dsq_010='B' then hccerxpd=0.33;
....

In which case you could make a macro with lines like this:

%macro translate(in,out);
if &in='A' then &out=0;
else if &in='B' then &out=0.33;
%mend ;

Which you could then use in a data step like this.

data want ;
  set have ;
  %translate(in=dsq_010,out=hccerxpd)
run;

 But it would probably be a lot easier to just create an informat and use that.

proc format ;
  invalue food
    'A' = 0
    'B' = 0.33
other = .
  ;
run;
data want ;
  set have;
  hccerxpd = input(dsq_010,food.);
run;
ballardw
Super User

One suspects that some instruction or code file from the NIH site was either not downloaded or misapplied.

 

Did you write those macros, copy them from the NIH site, get them from a coworker or some other source? Double check on the source.

 

I will reiterate about code boundaries.

If you have a data step that encounters a macro definition (%macro statement) then the data step ends. The same behavior occurs when a PROC statement is encountered.

A Proc, %macro , or Data statement ends any previous Data or Proc step.

 

If you wrote these "range" macros then show a working example without any macro coding.

If you got them from somewhere else go to that source and see if they had examples of actual use.

sas-innovate-2024.png

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 Bayesian Analysis?

Learn the difference between classical and Bayesian statistical approaches and see a few PROC examples to perform Bayesian analysis in this video.

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
  • 9 replies
  • 11384 views
  • 0 likes
  • 6 in conversation