BookmarkSubscribeRSS Feed
☑ This topic is solved. Need further help from the community? Please sign in and ask a new question.
DougHold
Obsidian | Level 7
%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.

1 ACCEPTED SOLUTION

Accepted Solutions
Quentin
Super User

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.

View solution in original post

5 REPLIES 5
ballardw
Super User

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

DougHold
Obsidian | Level 7
Good suggestion, thanks that works too.
Quentin
Super User

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.

DougHold
Obsidian | Level 7
Thank you, this is what I was looking for.
Tom
Super User Tom
Super User

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

 

How to Concatenate Values

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.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 5 replies
  • 1617 views
  • 0 likes
  • 4 in conversation