Hello,
I am developing a macro program to use for two different analyses. Below is a simplified version of the program. The actual program is much larger. I included a global macro variable "cohort" within the macro program. As you see below, for the first execution of the program, the variable "cohort" was assigned a null value. The entire program executed as desired for this step.
%let cohort = ;
%macro frequencies(year,var);
proc freq data=cohort_flags(where=(eligible=1 & year=&year &cohort)) noprint;
table &var / out=freq;
by orsid;
run;
%mend;
*Example;
%frequencies(2012,race);However, for the second analysis, I want to restrict incoming observations to those that have the same cohort allocation as a given year. What I want is to assign a value to the global macro variable "cohort" that acts as an additional statement within the where option. I know that the following is not valid syntax, but to communicate what I want, I would like the resolved macro variable to create code within the macro program that looks like this "and cohort = &year", with "year" calling the local macro variable. I have been experimenting with different combinations of %nrstr and %nrquote, but have been unsuccessful thus far. Below is an example of my last failed experiment.
%let cohort = %nrstr(and cohort = &year);
%let cohort = %nrstr(and cohort = %nrquote(%unquote(&year));I keep getting the error message
ERROR 22-322: Missing ')' parenthesis
I would greatly appreciate your help in creating a global macro variable that resolves within the macro program to reference the local macro variable "year".
Thanks,
So you want to get the value of COHORT to be the string:
and cohort = &year
That is easy to do with a DATA step.
data _null_;
call symputx('cohort','and cohort = &year');
run;
Much harder to do with pure macro code. Here is a trick that should work.
%let cohort=and cohort = &&%upcase(year);
The macro processor will evaluate && to &, but the use of the macro function around YEAR prevents the macro processor from then trying to resolve &YEAR.
One more closing parenthesis &year)));
%let cohort = %nrstr(and cohort = %nrquote(%unquote(&year)));
Hi @novinosrin
I added the extra parenthesis as you suggested. Below is a copy of the log with the full macro in it.
9803 options mprint symbolgen mlogic;
9804 %macro frequencies(year,var,missing);
9805 %put Output frequencies of categories by ORSID;
9806 proc freq data=cohort_flags(where=(eligible=1 & year=&year &cohort)) noprint;
9807 table &var / out=freq;
9808 by orsid;
9809 run;
9810 %put Separate duplicates & ensure correct number of total enrollees for &year;
9811 proc sort data=freq nodupkey
9812 out=enrollee_count
9813 dupout=duplicates;
9814 by orsid;
9815 run;
9816 %put Ensure duplicate observations are not missing;
9817 data anymissing;
9818 set duplicates (where=(&var=&missing));
9819 run;
9820 %put Print frequency counts and missing observations;
9821 proc freq data=freq (drop=count percent);
9822 table &var;
9823 run;
9824 %mend;
9825 %let cohort = %nrstr(and cohort = %nrquote(%unquote(&year)));
9826 %frequencies(2012,new_race,.);
MLOGIC(FREQUENCIES): Beginning execution.
MLOGIC(FREQUENCIES): Parameter YEAR has value 2012
MLOGIC(FREQUENCIES): Parameter VAR has value new_race
MLOGIC(FREQUENCIES): Parameter MISSING has value .
MLOGIC(FREQUENCIES): %PUT Output frequencies of categories by ORSID
Output frequencies of categories by ORSID
SYMBOLGEN: Macro variable YEAR resolves to 2012
SYMBOLGEN: Macro variable COHORT resolves to and cohort = %nrquote(%unquote(&year))
SYMBOLGEN: Some characters in the above value which were subject to macro quoting have been
unquoted for printing.
NOTE 137-205: Line generated by the invoked macro "FREQUENCIES".
1 proc freq data=cohort_flags(where=(eligible=1 & year=&year &cohort)) noprint; table &var
-
22
1 ! / out=freq; by orsid; run;
ERROR 22-322: Missing ')' parenthesis for data set option list
NOTE: Line generated by the invoked macro "FREQUENCIES".
1 proc freq data=cohort_flags(where=(eligible=1 & year=&year &cohort)) noprint; table &var
-
79
1 ! / out=freq; by orsid; run;
ERROR 79-322: Expecting a ).
NOTE: Line generated by the macro variable "COHORT".
1 and cohort = %nrquote(%unquote(&year))
-
22
-
76
ERROR: Syntax error while parsing WHERE clause.
MPRINT(FREQUENCIES): proc freq data=cohort_flags(where=(eligible=1 & year=2012 and cohort =
%nrquote(%unquote(&year)))) noprint;
SYMBOLGEN: Macro variable VAR resolves to new_race
MPRINT(FREQUENCIES): table new_race / out=freq;
MPRINT(FREQUENCIES): by orsid;
MPRINT(FREQUENCIES): run;
ERROR 22-322: Syntax error, expecting one of the following: a name, a quoted string,
a numeric constant, a datetime constant, a missing value, (, *, +, -, :, INPUT, NOT,
PUT, ^, ~.
ERROR 76-322: Syntax error, statement will be ignored.
NOTE: The SAS System stopped processing this step because of errors.
WARNING: The data set WORK.FREQ may be incomplete. When this step was stopped there were 0
observations and 0 variables.
WARNING: Data set WORK.FREQ was not replaced because this step was stopped.
NOTE: PROCEDURE FREQ used (Total process time):
real time 0.05 seconds
cpu time 0.04 seconds
MLOGIC(FREQUENCIES): %PUT Separate duplicates & ensure correct number of total enrollees for &year
SYMBOLGEN: Macro variable YEAR resolves to 2012
Separate duplicates & ensure correct number of total enrollees for 2012
MPRINT(FREQUENCIES): proc sort data=freq nodupkey out=enrollee_count dupout=duplicates;
MPRINT(FREQUENCIES): by orsid;
ERROR: Variable ORSID not found.
MPRINT(FREQUENCIES): run;
NOTE: The SAS System stopped processing this step because of errors.
WARNING: The data set WORK.ENROLLEE_COUNT may be incomplete. When this step was stopped there were
0 observations and 0 variables.
WARNING: Data set WORK.ENROLLEE_COUNT was not replaced because this step was stopped.
WARNING: The data set WORK.DUPLICATES may be incomplete. When this step was stopped there were 0
observations and 0 variables.
WARNING: Data set WORK.DUPLICATES was not replaced because this step was stopped.
NOTE: PROCEDURE SORT used (Total process time):
real time 0.01 seconds
cpu time 0.00 seconds
MLOGIC(FREQUENCIES): %PUT Ensure duplicate observations are not missing
Ensure duplicate observations are not missing
MPRINT(FREQUENCIES): data anymissing;
SYMBOLGEN: Macro variable VAR resolves to new_race
SYMBOLGEN: Macro variable MISSING resolves to .
MPRINT(FREQUENCIES): set duplicates (where=(new_race=.));
ERROR: Variable new_race is not on file WORK.DUPLICATES.
MPRINT(FREQUENCIES): run;
NOTE: The SAS System stopped processing this step because of errors.
WARNING: The data set WORK.ANYMISSING may be incomplete. When this step was stopped there were 0
observations and 0 variables.
WARNING: Data set WORK.ANYMISSING was not replaced because this step was stopped.
NOTE: DATA statement used (Total process time):
real time 0.01 seconds
cpu time 0.00 seconds
MLOGIC(FREQUENCIES): %PUT Print frequency counts and missing observations
Print frequency counts and missing observations
MPRINT(FREQUENCIES): proc freq data=freq (drop=count percent);
ERROR: The variable count in the DROP, KEEP, or RENAME list has never been referenced.
ERROR: The variable percent in the DROP, KEEP, or RENAME list has never been referenced.
SYMBOLGEN: Macro variable VAR resolves to new_race
MPRINT(FREQUENCIES): table new_race;
ERROR: No data set open to look up variables.
MPRINT(FREQUENCIES): run;
NOTE: The SAS System stopped processing this step because of errors.
NOTE: PROCEDURE FREQ used (Total process time):
real time 0.01 seconds
cpu time 0.01 seconds
MLOGIC(FREQUENCIES): Ending execution.
So you want to get the value of COHORT to be the string:
and cohort = &year
That is easy to do with a DATA step.
data _null_;
call symputx('cohort','and cohort = &year');
run;
Much harder to do with pure macro code. Here is a trick that should work.
%let cohort=and cohort = &&%upcase(year);
The macro processor will evaluate && to &, but the use of the macro function around YEAR prevents the macro processor from then trying to resolve &YEAR.
Hi @Tom,
Thank you for your help. I used the macro code you provided, and it worked well.
Thanks,
Ted
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!
SAS' Charu Shankar shares her PROC SQL expertise by showing you how to master the WHERE clause using real winter weather data.
Find more tutorials on the SAS Users YouTube channel.