Hi all,
I am trying to write a macro where the first step creates some stats from a t-test, then I do some additional work on the ods output and refer to it by the macro deined "%let" name. I keep getting a "Error 180-322: Statement is not valid or it is used out of proper order" with by step statement in a data step. I'm at a loss. Below is a snippet of the macro:
%macro m1 (varlist);
%local i next ;
%let i=1;
%do i=1 %to %sysfunc(countw(&varlist));
%let next=%scan(&varlist,&i);
* Step 1;
%let lib1 = work;
%let lib2 = work;
%let fileorg = survey_of_interest;
%let pre = &next;
%let survey = "&next";
DATA survey_of_interest;
SET data_raw_2;
WHERE survey_name = &survey;
RUN;
ods output "Statistics" = &pre.stats
"T-Tests" = &pre.ttests
"Equality of Variances" = &pre.vars;
proc ttest data=&lib2..&fileorg;
class finaid;
*by survey_name;
var _numeric_;
run;
ods output close;
*Step 2;
*%let lib1 = work;
*%let pre = finaid_css;
data &pre.stats1 (keep = survey_name variable class
mean_nonfinaid mean_finaid pooled_sd);
set work.&&pre.stats (rename=(mean=avg));
%if class = '0'
%then mean_nonfinaid = avg;
%if class = '1'
%then mean_finaid = avg;
%if class = 'Diff (1-2)'
%then pooled_sd = StdDev;
run;
%end;
%mend m1;
%m1(CSS);
I seem to have all the semicolons, but I don't know what is happening.
Please look at this from your code:
data &pre.stats1 (keep = survey_name variable class
mean_nonfinaid mean_finaid pooled_sd);
set work.&&pre.stats
The last is going to be looking for a macro variable named something that I don't think exists.
If you run your code with
Options Mprint Symbolgen;
before executing the macro the log will likely give you more information about what you actually created.
Turn off with
Options Nomprint Nosymbolgen;
Also you used some comments here:
ods output close; *Step 2; *%let lib1 = work; *%let pre = finaid_css;
Which may cause unexpected results.
Inside a macro block you want comments to be either
/* %let lib1=work; */
or
%* %let lib1 = work;
For a number of reasons I always use the /* */ comment. One reason: editor support for comment /uncomment with Ctrl-/ and Shift-Ctrl-/
*Step 2;
*%let lib1 = work;
*%let pre = finaid_css;
data &pre.stats1 (keep = survey_name variable class
mean_nonfinaid mean_finaid pooled_sd);
set work.&&pre.stats (rename=(mean=avg));
%if class = '0'
%then mean_nonfinaid = avg;
%if class = '1'
%then mean_finaid = avg;
%if class = 'Diff (1-2)'
%then pooled_sd = StdDev;
run;
%end;
%mend m1;
%m1(CSS);
Assuming Class is a variable in the dataset specified in set statement, I do not get why you are using macro %if %then statements to evaluate datastep variables such as class, shouldn't it be just if then statements?
Please look at this from your code:
data &pre.stats1 (keep = survey_name variable class
mean_nonfinaid mean_finaid pooled_sd);
set work.&&pre.stats
The last is going to be looking for a macro variable named something that I don't think exists.
If you run your code with
Options Mprint Symbolgen;
before executing the macro the log will likely give you more information about what you actually created.
Turn off with
Options Nomprint Nosymbolgen;
Also you used some comments here:
ods output close; *Step 2; *%let lib1 = work; *%let pre = finaid_css;
Which may cause unexpected results.
Inside a macro block you want comments to be either
/* %let lib1=work; */
or
%* %let lib1 = work;
For a number of reasons I always use the /* */ comment. One reason: editor support for comment /uncomment with Ctrl-/ and Shift-Ctrl-/
I killed the comments complete and the macro worked. I did not realise the funky behaviour with the comments with a single *;...The more you know!
Thanks everyone!
@dewittme wrote:
I killed the comments complete and the macro worked. I did not realise the funky behaviour with the comments with a single *;...The more you know!
Thanks everyone!
It has been quite a few years ago but I know I spent hours going over some simple code that I had made one small change to that blew up. This was pretty much before most of the internet on line forums existed so there was a lot of trial and error involved. And reading the documentation. Once I had a clue where to look it was there but not the most obvious thing to chase down.
SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!
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.