BookmarkSubscribeRSS Feed
☑ This topic is solved. Need further help from the community? Please sign in and ask a new question.
GeorgeBonanza
Obsidian | Level 7

Below is a simplified example of what I am trying to do.  I'd like to know if it is possible to replace the case statement with a concatenation of "DISCOUNT_" and the value of ID and then return the value of that macro variable.  For example, the first record of the HAVE dataset would first concatenate "DISCOUNT_" and "001" and then return 0.1, the value of DISCOUNT_001 variable.  Essentially, the equivalent of &DISCOUNT_001.

 

Any insight is appreciated.  Thanks in advance.

 

%let DISCOUNT_001 = 0.1;
%let DISCOUNT_002 = 0.05;

data HAVE;
	input ID $ QTY UNIT;
	datalines;
001 2 500
001 4 500
002 3 300
002 1 300
;
run;

proc sql; create table WANT as
	select ID, SUM(QTY * UNIT * (1 - case ID when "001" then &DISCOUNT_001 when "002" then &DISCOUNT_002 else 0 end)) as REVENUE
	from HAVE
	group by 1;
quit;
1 ACCEPTED SOLUTION

Accepted Solutions
Quentin
Super User

Technically, you could, by SYMGET to resolve the macro variable when the code executes, e.g.:

 

proc sql; create table WANT as
	select ID, SUM(QTY * UNIT * (1 - input(symget(cats("Discount_",ID)),8.) )) as REVENUE
	from HAVE
	group by 1;
quit;

But this would be an unusual way to do a look-up in SAS.  In SQL, you could consider joining on a table with the discount value for each ID.  Or another common way to do a lookup in SAS is with a format or informat, e.g.:

 

proc format ;
  invalue disc
  '001'=.1
  '002'=.05
  ;
run ;

proc sql; create table WANT as
	select ID, SUM(QTY * UNIT * ( 1 - input(ID,disc.) )) as REVENUE
	from HAVE
	group by 1;
quit;
The Boston Area SAS Users Group is hosting free webinars!
Next webinar will be in January 2025. Until then, check out our archives: https://www.basug.org/videos. And be sure to subscribe to our our email list.

View solution in original post

3 REPLIES 3
Quentin
Super User

Technically, you could, by SYMGET to resolve the macro variable when the code executes, e.g.:

 

proc sql; create table WANT as
	select ID, SUM(QTY * UNIT * (1 - input(symget(cats("Discount_",ID)),8.) )) as REVENUE
	from HAVE
	group by 1;
quit;

But this would be an unusual way to do a look-up in SAS.  In SQL, you could consider joining on a table with the discount value for each ID.  Or another common way to do a lookup in SAS is with a format or informat, e.g.:

 

proc format ;
  invalue disc
  '001'=.1
  '002'=.05
  ;
run ;

proc sql; create table WANT as
	select ID, SUM(QTY * UNIT * ( 1 - input(ID,disc.) )) as REVENUE
	from HAVE
	group by 1;
quit;
The Boston Area SAS Users Group is hosting free webinars!
Next webinar will be in January 2025. Until then, check out our archives: https://www.basug.org/videos. And be sure to subscribe to our our email list.
ballardw
Super User

SYMGET is the function I think you want:

data HAVE;
	input ID $ QTY UNIT;
        z = symget(cats('DISCOUNT_',id));
	datalines;
001 2 500
001 4 500
002 3 300
002 1 300
;
run;

Though may take an extra step to get a numeric value as the result is character

Maybe (as I'm not really sure what you expect as a result)

proc sql; create table WANT as
	select ID, SUM(QTY * UNIT * (1 - input(symget(cats('DISCOUNT_',id)),8.))) as REVENUE
	from HAVE
	group by 1;
quit;
GeorgeBonanza
Obsidian | Level 7
The SYMGET function is what I needed. Another user suggested the same thing just before you did. Thank you for taking the time to reply.

SAS Innovate 2025: Register Now

Registration is now open for SAS Innovate 2025 , our biggest and most exciting global event of the year! Join us in Orlando, FL, May 6-9.
Sign up by Dec. 31 to get the 2024 rate of just $495.
Register now!

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
  • 3 replies
  • 1085 views
  • 1 like
  • 3 in conversation