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

Dear community,

 

I have been requested to provide a report in which mean, median, max, min and stdev are supposed to be shown in two rows: mean (std) and median(min-max) - and in this format. My existing code relies on having the results in a numeric column, which concatenated statistics are not:

%macro characteristics_sql_num(total=);
	select "MSRP" length=100 as Characteristics,
		"&summary_function" length=100 label=" " as Value,
		%if %length(&total) GT 0 %then &total as;
	Origin,
		&summary_function(MSRP) format=5.1 as result
		from sashelp.cars
		%if %length(&total) EQ 0 %then group by Origin;
%mend characteristics_sql_num;

%macro characteristics_num;
	%let summary_functions = mean std min median max;

	proc sql;
		create table cars_summary as

			%do i = 1 %to %sysfunc(countw(&summary_functions));
				%let summary_function = %scan(&summary_functions, &i);

				%if &i NE 1 %then
					union;

				%characteristics_sql_num
				union
				%characteristics_sql_num(total="Total")
			%end;
		;
%mend characteristics_num;

%characteristics_num

proc report data=cars_summary;
columns Characteristics Value Origin, result;
define Characteristics -- Value / group;
define Origin / across;
define result / " " format=best6.;
run;

I tried inserting the needed rows with break after and compute after, but this unfortunately does not work. Is there a way of generating the needed rows during proc report, or should I rather rebuild my macro to generate the needed concatenations already during proc sql? Thank you for your support in advance.

1 ACCEPTED SOLUTION

Accepted Solutions
BrunoMueller
SAS Super FREQ

Going with your Proc SQL approach, I would combine the stats already in the Proc SQL into a single var so Proc REPORT will just do the display.

 

Here is an example


proc sql;
  create table result as
  select
    "MSRP" as characteristic
    , origin
    , "mean (std)" as value
    , cats(mean(msrp), "(", std(msrp), ")") as cell
  from
    sashelp.cars
  group by
     origin

  union

  select
    "MSRP" as characteristic
    , origin
    , "median (range)" as value
    , cats(median(msrp), "(", catx(" ", min(msrp), max(msrp)), ")") as cell
  from
    sashelp.cars
  group by
    origin
   union
     select
    "MSRP" as characteristic
    , "Total"
    , "mean (std)" as value
    , cats(mean(msrp), "(", std(msrp), ")") as cell
  from
    sashelp.cars

  union

  select
    "MSRP" as characteristic
    , "Total"
    , "median (range)" as value
    , cats(median(msrp), "(", catx(" ", min(msrp), max(msrp)), ")") as cell
  from
    sashelp.cars
  ;
quit;

proc report data=result;
  column characteristic value Origin, cell;
  define characteristic / group ;
  define value / group ;
  define origin / across ;
  define cell / group " " style={textalign=right};
run;

View solution in original post

3 REPLIES 3
BrunoMueller
SAS Super FREQ

Not knowing how exactly the output needs to look (an example would help very much). Have a look at Proc TABULATE, it allows to have statistics on the row level.

 

See example below


proc tabulate data=sashelp.cars format=comma14.2;
  class origin;
  var msrp;
  table
    msrp="stats 1"*(mean std)
    msrp="stats 2"*(min median max)
    ,
    origin=" " all
  ;
run;
js5
Pyrite | Level 9 js5
Pyrite | Level 9

Thanks for responding! Switching to proc tabulate would unfortunately mean rewriting much of the available macros so I am afraid it is not feasible. It would probably be easier to adapt proc sql statements. Below is what I have vs what has been requested:

numeric_stats.png

As I am using ODS excel, maybe there could be a way of putting in a formula which generates the needed format instead of handling it all in proc report?

BrunoMueller
SAS Super FREQ

Going with your Proc SQL approach, I would combine the stats already in the Proc SQL into a single var so Proc REPORT will just do the display.

 

Here is an example


proc sql;
  create table result as
  select
    "MSRP" as characteristic
    , origin
    , "mean (std)" as value
    , cats(mean(msrp), "(", std(msrp), ")") as cell
  from
    sashelp.cars
  group by
     origin

  union

  select
    "MSRP" as characteristic
    , origin
    , "median (range)" as value
    , cats(median(msrp), "(", catx(" ", min(msrp), max(msrp)), ")") as cell
  from
    sashelp.cars
  group by
    origin
   union
     select
    "MSRP" as characteristic
    , "Total"
    , "mean (std)" as value
    , cats(mean(msrp), "(", std(msrp), ")") as cell
  from
    sashelp.cars

  union

  select
    "MSRP" as characteristic
    , "Total"
    , "median (range)" as value
    , cats(median(msrp), "(", catx(" ", min(msrp), max(msrp)), ")") as cell
  from
    sashelp.cars
  ;
quit;

proc report data=result;
  column characteristic value Origin, cell;
  define characteristic / group ;
  define value / group ;
  define origin / across ;
  define cell / group " " style={textalign=right};
run;

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!

What is Bayesian Analysis?

Learn the difference between classical and Bayesian statistical approaches and see a few PROC examples to perform Bayesian analysis in this video.

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
  • 3 replies
  • 782 views
  • 0 likes
  • 2 in conversation