Hello,
The result is 67, how can apply percent7.2 format to the result? Thanks!
%let num=%eval((60+75)/2);
%put #
Do you just want the number? Or do you want the 7 character string that the 7.2 format would produce from that number?
%EVAL() only does integer arithmetic. To do real valued arithmetic in macro logic use %SYSEVALF() instead.
1 %put num=%eval((60+75)/2); num=67 2 %put num=%sysevalf((60+75)/2); num=67.5
If you want to use a format to produce a string in particular style the use %SYSFUNC(). You could use it to call the PUTN() function.
3 %put num=%sysfunc(putn((60+75)/2,7.2)); num= 67.50
Notice that generated string is now 7 characters long (including the two leading spaces) instead of the four required to represent the number 67.5.
Or you can just include the format specification in the %SYSFUNC() call. For example it looks like want you want is the mean of 60 and 75. So use %SYSFUNC() to call the MEAN() function instead of the PUTN() function.
4 %put num=%sysfunc(mean(60,75),7.2); num= 67.50
The result is supposed to be 67, and the result is not 67.5. This has nothing to do with formatting. Why? Because %eval() does integer arithmetic. It doesn't know about fractions or decimals.
If you want to do floating point arithmetic with macro variables, and you in this case you want the answer to be 67.5, use %sysevalf()
Thanks a lot, Paige! this is what I tried out:
Which brings up the question: WHY?
Are you just trying to learn macro functions? Or do you actually have a use for doing artihmetic and storing these decimal values in a macro variable? Usually, arithmetic like this and decimal values like this ought to be created and stored in a SAS data set, not in a macro variable.
Also, please from now on post the code and log as text, not as screen captures.
Do you just want the number? Or do you want the 7 character string that the 7.2 format would produce from that number?
%EVAL() only does integer arithmetic. To do real valued arithmetic in macro logic use %SYSEVALF() instead.
1 %put num=%eval((60+75)/2); num=67 2 %put num=%sysevalf((60+75)/2); num=67.5
If you want to use a format to produce a string in particular style the use %SYSFUNC(). You could use it to call the PUTN() function.
3 %put num=%sysfunc(putn((60+75)/2,7.2)); num= 67.50
Notice that generated string is now 7 characters long (including the two leading spaces) instead of the four required to represent the number 67.5.
Or you can just include the format specification in the %SYSFUNC() call. For example it looks like want you want is the mean of 60 and 75. So use %SYSFUNC() to call the MEAN() function instead of the PUTN() function.
4 %put num=%sysfunc(mean(60,75),7.2); num= 67.50
Thanks a lot, Tom! This is what I tried and get, I think you solved several questions I encountered when struggled with this.
Also ... if your title is a good description of what you want to do, you really want a macro variable formatted at percent7.2 (not 7.2), please understand a few things
%let num=%sysfunc(putn(%eval((60+75)/2),percent7.2));
%put &=num;
or
%let num=%eval((60+75)/2);
%put %sysfunc(putn(&num,percent7.2));
Thanks a lot, Paige! This is what I tried:
%put num=%sysfunc(putn(%eval((60+75)/2),percent7.2));
%let num=%eval((60+75)/2);
%put %sysfunc(putn(&num,percent7.2));
%put %sysfunc(putn(&num/100,percent7.2));
%put %sysfunc(putn(&num/100,percent8.2));
The results is as follows (I somehow cannot copy any text in my log so have to use screenshot):
Therefore, if I want to use a macro (either use a %let statement or a %let and a %put statement) to calculate the mean of several numbers and get a result in a format of xx.xx% (5 digits including two decimal places, in percent), the best steps (and it looks like the correct percent format is percent8.2, not percent7.2) are 1) use a %let and %eval to calculate the number, and 2) use %sysfunc(putn(&number/100,percent8.2)) in the %put statement to display the number in a percent8.2 format.
%let num=%eval((60+75)/2);
%put %sysfunc(putn(&num/100,percent8.2));
I have not think the question of store or reuse a macro yet. What I am doing is just use macro to write something and get the result or output (a number, a calculation, a table, or a dataset) according to what I want to produce. As for the above example, the other simpler solution is, if I just want the number without the percent sign % (and this perhaps is the common practice in real scenario, as Paige mentioned in the post and what I myself agree, the % sign and other symbol such as & could cause trouble in macro), I can simply use 1) the %sysevalf() to get the result with up to 14 decimal places or 2) the %sysfunc(putn(),5.2) and %sysfunc(mean(),5.2) in Tom's above post, to get the result in a 5.2 format, like this:
%put num=%sysevalf((62.5+76+80.5)/3);
%put num3=%sysfunc(putn((62.5+76+80.5)/3,5.2));
%put num4=%sysfunc(mean(70,60.5,62.87,82,70),5.2);
@dxiao2017 wrote:
Therefore, if I want to use a macro (either use a %let statement or a %let and a %put statement) to calculate the mean of several numbers and get a result in a format of xx.xx% (5 digits including two decimal places, in percent), the best steps (and it looks like the correct percent format is percent8.2, not percent7.2) are
1) use a %let and %eval to calculate the number, and 2) use %sysfunc(putn(&number/100,percent8.2)) in the %put statement to display the number in a percent8.2 format.
I disagree with the above. Do the math in a DATA step. Don't do this type of math using macro variables.
Hi Paige, thanks for the suggestion. You suggest that the good way to do the math is a data step, not a macro because a macro here is not necessary and perhaps easy to cause trouble. Below is what I have being doing before, and after I begin learning macro I tried calculate this through a macro because I want to learn macro.
data _null_;
num=(60+75)/2;
format num 5.2;
put num=;
run;
data _null_;
num=((60+75)/2)/100;
format num percent8.2;
put num=;
run;
And when just began learn base and sql, most often I create a dataset and then use proc means or proc sql to calculate mean statistics like this:
data num;
input num;
numpct=put(num/100,percent8.2);
datalines;
70
60.5
62.87
82
70
;
run;
proc print data=num;run;
proc means data=num n mean maxdec=2;
var num;
run;
proc sql number;
select * from num;
select count(num) as n,
avg(num)/100 as mean format=percent8.2
from num;
quit;
It's finally time to hack! Remember to visit the SAS Hacker's Hub regularly for news and updates.
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.
Ready to level-up your skills? Choose your own adventure.