BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
Christen
Fluorite | Level 6

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.Dataset.PNG
Thank you!
 

 

 

1 ACCEPTED SOLUTION

Accepted Solutions
RichardDeVen
Barite | Level 11

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

RichardADeVenezia_0-1608998732049.png

 

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.

View solution in original post

5 REPLIES 5
PaigeMiller
Diamond | Level 26

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.

--
Paige Miller
Christen
Fluorite | Level 6
I understand that I can do it without a macro, but in my task says that it must necessarily be used. I was thinking about the round function, but I don't understand how to write it correctly into a macro
PaigeMiller
Diamond | Level 26

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.

--
Paige Miller
RichardDeVen
Barite | Level 11

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

RichardADeVenezia_0-1608998732049.png

 

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.

PaigeMiller
Diamond | Level 26

Good points, @RichardDeVen, which I hadn't even thought of. I see you don't find the need to use macros either. 👍

--
Paige Miller

SAS Innovate 2025: Call for Content

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!

Submit your idea!

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
  • 1798 views
  • 3 likes
  • 3 in conversation