%let CPI2017 = 110;
%let Y = 2020;
Data _null_;
%put CPI in 2017 is &CPI2017;
%put CPI in %eval(&Y-3) is &CPI%eval(&Y-3);
Why does the second put statement not produce the same result as the first one (I get a warning)? I thought maybe I need double ampersand, like this.
%put CPI in %eval(&Y-3) is &&CPI%eval(&Y-3);
But that also doesn't work, I still only get "CPI in 2017 is &CPI2017".
What I want is "CPI in 2017 is 110", just like the first statement.
Hi,
Double (or triple) ampersands can't help you here. I often think they will, but they can't help you build a macro token when part of the token comes from executing a macro.
One way to get what you want is to use %unquote(). Unquote can also be used to 'glue' text together to make a single token, e.g.:
1 %let CPI2017 = 110;
2 %let Y = 2020;
3
4 %put CPI in 2017 is &CPI2017;
CPI in 2017 is 110
5 %put CPI in %eval(&Y-3) is %unquote(%nrstr(&CPI)%eval(&Y-3));
CPI in 2017 is 110
So %nrstr() is used above to mask the &, then %eval() executes, then %unquote unmasks the & and &CPI2017 resolves.
I think the %eval is leaving SAS looking for a simple &cpi variable, which you don't have.
If you remove the %eval this way
%let t=%eval(&Y-3); %put CPI in %eval(&Y-3) is &&CPI&t;
Yields
CPI in 2017 is 110
Hi,
Double (or triple) ampersands can't help you here. I often think they will, but they can't help you build a macro token when part of the token comes from executing a macro.
One way to get what you want is to use %unquote(). Unquote can also be used to 'glue' text together to make a single token, e.g.:
1 %let CPI2017 = 110;
2 %let Y = 2020;
3
4 %put CPI in 2017 is &CPI2017;
CPI in 2017 is 110
5 %put CPI in %eval(&Y-3) is %unquote(%nrstr(&CPI)%eval(&Y-3));
CPI in 2017 is 110
So %nrstr() is used above to mask the &, then %eval() executes, then %unquote unmasks the & and &CPI2017 resolves.
Don't do that. Macro language is complex enough, it not worth trying overcomplicate things just to save a line of code.
Use the %EVAL() to generate a new variable.
Either one with the NAME of the macro variable you want.
Or one with the YEAR value you want.
1031 %let name=CPI%eval(&y-3); 1032 %put CPI in %eval(&Y-3) is &&&name; CPI in 2017 is 110 1033 %let year=%eval(&y-3); 1034 %put CPI in %eval(&Y-3) is &&CPI&year; CPI in 2017 is 110
Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!
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.