Hello! Could you plese help me with my task? I need create a macro wich change the number of decimal.
Default: N 0; Mean 1; SD 2; Median 1; Min Max 1.
For Temperature set N 0; Mean 2; SD 3; Median 2; Min Max 2.
For Systolic/Diastolic BP set N 0; Mean 1; SD 1; Median 1; Min Max 0.
For others leave default.
So, I have raw data, then I apply proc means and get statistics.
proc means data = vs n mean median std min max noprint nway;
var aval;
class paramcd;
output out = vsstat(drop= _TYPE_ _FREQ_) n =
mean =
std =
median =
min =
max = / autoname;
run;
After proc means I need to create a macro with the conditions that were above. My vsstat looks like this.
Thank you!
Is your task a homework or school assignment ?
Even if you round a value to a certain level of decimal precision, the display of that value is dependent on the variables format. A variables format can not be changed row by row in the default viewers such as table viewer, view table or fsview. Likewise, in default output as such from Proc PRINT will have a variables value displaying with a fixed static format, and will not change dependent on your 'parmcd'.
if parmcd = 'whatever' then x = round (x, 0.1); else x = round (x, 0.01); format x 12.2;
The whatever parm x-values will always show two decimal places in the viewers as ##.d0
A Proc REPORT can create output with varying format displays by using COMPUTE blocks that utilize CALL DEFINE ('<varname>', 'FORMAT', '<my-conditional-format>')
Example:
title; footnote; data have; infile cards dlm=','; length parmcd $15; input parmcd aval_n aval_mean aval_stddev aval_median aval_min aval_max; format _numeric_ best12.; datalines; BP DIASTOLIC, 936, 70.977564103, 7.524827274, 71, 50, 107 BP SYSTOLIC , 936, 117.76709402, 10.320180454, 117, 90, 149 PULSE, 936, 71.036324786, 11.074698483, 69, 49, 110 RESPIRATION, 936, 17.879273504, 1.4215145595, 18, 12, 24 TEMPERATURE, 936, 97.752457265, 0.6521985429, 97.7,95.6,99.5 ; ods html file='report.html' style=plateau; proc report data=have; columns parmcd aval_: dummy; define _all_ / display; define dummy / computed noprint; define aval_mean / format=12.1; compute dummy; select (parmcd); when ('TEMPERATURE') do; call define('aval_mean', 'format', '12.2');
end; otherwise; end; endcomp; run; ods html close;
Produces an output with a format applied conditionally to values
You can use a control data set and macro coding to generate the source code that is the conditional application of formats in a proc report compute block.
Are you thinking about using the ROUND function to limit the number of decimal places?
Do you want this limited number of decimal places in a report? Or somewhere else?
There's no need to use a macro, either a data step or PROC REPORT will get you there.
So, @Christen , this comment is not directed at you but at whoever insists that macros be used here.
I think that when you are learning to use macros, you also need to learn when NOT to use macros, and so the assignment requiring you to solve the problems with macros is a poor assignment that teaches the wrong lessons.
For anyone else reading along, here is a solution that doesn't use macros
data want;
set vsstat;
if parmcd='TEMPERATURE' then do;
aval_mean=round(aval_mean,0.01);
aval_stddev=round(aval_stddev,0.001);
aval_median=round(aval_median,0.01);
aval_min=round(aval_min,0.01);
aval_max=round(aval_max,0.01);
end;
else if parmcd='BP SYSTOLIC' then do;
/* Then you repeat the above with modifications to the ROUND function */
/* for the other variables, but I'm lazy so I didn't do it */
end;
run;
Similar use of the ROUND function can be done in PROC REPORT rather than a DATA step. Or in PROC REPORT, you can use formats to control the number of decimal places.
Is your task a homework or school assignment ?
Even if you round a value to a certain level of decimal precision, the display of that value is dependent on the variables format. A variables format can not be changed row by row in the default viewers such as table viewer, view table or fsview. Likewise, in default output as such from Proc PRINT will have a variables value displaying with a fixed static format, and will not change dependent on your 'parmcd'.
if parmcd = 'whatever' then x = round (x, 0.1); else x = round (x, 0.01); format x 12.2;
The whatever parm x-values will always show two decimal places in the viewers as ##.d0
A Proc REPORT can create output with varying format displays by using COMPUTE blocks that utilize CALL DEFINE ('<varname>', 'FORMAT', '<my-conditional-format>')
Example:
title; footnote; data have; infile cards dlm=','; length parmcd $15; input parmcd aval_n aval_mean aval_stddev aval_median aval_min aval_max; format _numeric_ best12.; datalines; BP DIASTOLIC, 936, 70.977564103, 7.524827274, 71, 50, 107 BP SYSTOLIC , 936, 117.76709402, 10.320180454, 117, 90, 149 PULSE, 936, 71.036324786, 11.074698483, 69, 49, 110 RESPIRATION, 936, 17.879273504, 1.4215145595, 18, 12, 24 TEMPERATURE, 936, 97.752457265, 0.6521985429, 97.7,95.6,99.5 ; ods html file='report.html' style=plateau; proc report data=have; columns parmcd aval_: dummy; define _all_ / display; define dummy / computed noprint; define aval_mean / format=12.1; compute dummy; select (parmcd); when ('TEMPERATURE') do; call define('aval_mean', 'format', '12.2');
end; otherwise; end; endcomp; run; ods html close;
Produces an output with a format applied conditionally to values
You can use a control data set and macro coding to generate the source code that is the conditional application of formats in a proc report compute block.
Good points, @RichardDeVen, which I hadn't even thought of. I see you don't find the need to use macros either. 👍
Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!
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.