- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
I just started learning SAS.
I am trying to multiply variable by macro function.
I have a dataset
DATA DATA1; input SCORE; DATALINES; 100 ;
I would like to multiple score by 10 or divide score by 10
I tried like this
%macro multiple; DATA try; set DATA1; call symput("anotherscore",SCORE); %let anotherscore=%eval(&anotherscore*10); %put &anotherscore; run; %mend;
try dataset has been created but it is not multiplied by 10. How can I do it?
Accepted Solutions
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
UCLA introductory tutorial on macro variables and macros
https://stats.idre.ucla.edu/sas/seminars/sas-macros-introduction/
Tutorial on converting a working program to a macro
This method is pretty robust and helps prevent errors and makes it much easier to debug your code. Obviously biased, because I wrote it 🙂 https://github.com/statgeek/SAS-Tutorials/blob/master/Turning%20a%20program%20into%20a%20macro.md
Examples of common macro usage
https://communities.sas.com/t5/SAS-Communities-Library/SAS-9-4-Macro-Language-Reference-Has-a-New-Ap...
%macro multiple;
DATA try;
set DATA1;
*creates macro variable - no need to create intermediate variable;
call symputx('anotherscore', score*10, g);
run;
%mend;
%multiple;
%put &anotherscore.;
You have a couple of issues going on here:
- mixing macro and data step code (%LET versus CALL SYMPUTX())
- macro scope - what exists inside macro is different than outside
- when macro variables are compiled/available
So overall, the optimal solution depends on what you're trying to do....another option
%let score = 100;
%let anotherscore = %sysevalf(&score*10);
%put score.;
%put anotherScore.;
@mutohai wrote:
I just started learning SAS.
I am trying to multiply variable by macro function.
I have a dataset
DATA DATA1; input SCORE; DATALINES; 100 ;I would like to multiple score by 10 or divide score by 10
I tried like this
%macro multiple; DATA try; set DATA1; call symput("anotherscore",SCORE); %let anotherscore=%eval(&anotherscore*10); %put &anotherscore; run; %mend;try dataset has been created but it is not multiplied by 10. How can I do it?
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
UCLA introductory tutorial on macro variables and macros
https://stats.idre.ucla.edu/sas/seminars/sas-macros-introduction/
Tutorial on converting a working program to a macro
This method is pretty robust and helps prevent errors and makes it much easier to debug your code. Obviously biased, because I wrote it 🙂 https://github.com/statgeek/SAS-Tutorials/blob/master/Turning%20a%20program%20into%20a%20macro.md
Examples of common macro usage
https://communities.sas.com/t5/SAS-Communities-Library/SAS-9-4-Macro-Language-Reference-Has-a-New-Ap...
%macro multiple;
DATA try;
set DATA1;
*creates macro variable - no need to create intermediate variable;
call symputx('anotherscore', score*10, g);
run;
%mend;
%multiple;
%put &anotherscore.;
You have a couple of issues going on here:
- mixing macro and data step code (%LET versus CALL SYMPUTX())
- macro scope - what exists inside macro is different than outside
- when macro variables are compiled/available
So overall, the optimal solution depends on what you're trying to do....another option
%let score = 100;
%let anotherscore = %sysevalf(&score*10);
%put score.;
%put anotherScore.;
@mutohai wrote:
I just started learning SAS.
I am trying to multiply variable by macro function.
I have a dataset
DATA DATA1; input SCORE; DATALINES; 100 ;I would like to multiple score by 10 or divide score by 10
I tried like this
%macro multiple; DATA try; set DATA1; call symput("anotherscore",SCORE); %let anotherscore=%eval(&anotherscore*10); %put &anotherscore; run; %mend;try dataset has been created but it is not multiplied by 10. How can I do it?
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
Macros aren't the best tool to use when you want to perform arithmetic (other than integer addition). You'd be better off doing the arithmetic in a DATA step.
Paige Miller
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
You don't need a macro definition (no macro logic used), and you don't need macro arithmetic:
DATA try;
set DATA1;
call symputx("anotherscore",SCORE * 10);
run;
%put &anotherscore.;
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
PS the macro processor is for creating code, not for manipulating data. For data, you always use the DATA or PROC steps.
And if you just started learning SAS, it is WAY too early to dive into macro programming. You need to learn the Base language first, before you can use the macro processor to create code in that language.
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
Thank you for answering my question. I understand it. Thank you.
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
Your code has a timing issue. The macro processor scans the text first and passes the results onto SAS to run. So your %LET and %PUT will run before the SAS processor even starts to compile the data step and the macro variable ANOTHERSCORE will either not exist or have some other value. You essentially ran this code:
%let anotherscore=%eval(&anotherscore*10);
%put &anotherscore;
DATA try;
set DATA1;
call symput("anotherscore",SCORE);
run;
If you change the order so that the macro code runs after the data step has run then the value of the ANOTHERSCORE macro variable will be multiplied by 10 and the result printed to the log.
DATA try;
set DATA1;
call symput("anotherscore",SCORE);
run;
%let anotherscore=%eval(&anotherscore*10);
%put &anotherscore;
You also have two other problems here.
First the value of the macro variable changes over and over as the data step runs for each observation read from the input dataset DATA1. Only the value from the last observation will be in the macro variable when the data step is finished.
Second the %EVAL() function only works for integer arithmetic. If SCORE is not an integer then you need to use the %SYSEVALF() function instead.