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.

BASUG is hosting free webinars Next up: Mike Raithel presenting on validating data files on Wednesday July 17. Register now at the Boston Area SAS Users Group event page: https://www.basug.org/events.

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.

BASUG is hosting free webinars Next up: Mike Raithel presenting on validating data files on Wednesday July 17. Register now at the Boston Area SAS Users Group event page: https://www.basug.org/events.
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

 

Ready to join fellow brilliant minds for the SAS Hackathon?

Build your skills. Make connections. Enjoy creative freedom. Maybe change the world. Registration is now open through August 30th. Visit the SAS Hackathon homepage.

Register today!
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.

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
  • 5 replies
  • 601 views
  • 0 likes
  • 4 in conversation